#!/usr/bin/python
# -*- coding: latin1 -*-
"""

    Name: _brailleMusicML.py

    Author: Enrico Bortolazzi - Veia Progetti s.r.l.

    Comment: brailleMusicML utilities

    Version: 1.0

    Date: Fri Aug 17, 2007

------------------------------------------------------------------------

Copyright (c) 2007, Veia Progetti s.r.l. - http://www.veia.it

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    Redistributions of source code must retain the above copyright notice,
    this list of conditions and the following disclaimer.

    Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in
    the documentation and/or other materials provided with the distribution.

    Neither name of Veia Progetti s.r.l. nor the name of its contributors
    may be used to endorse or promote products derived from this software
    without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""

import weakref
import copy

version = '0.8'


def name_mangle(n):
    """ name mangling """
    if n in ['type', 'print', 'dir', 'id']:
        n += '_'
    elif n == 'xml:lang':
        n = 'lang'
    return n

def name_unmangle(n):
    """ name un-mangling """
    if n in ['type_', 'print_', 'dir_', 'id_']:
        n = n[:-1]
    elif n == 'lang':
        n = 'xml:lang'
    return n

#def xcapitalize(str, lead='_'):
#    """ capitalize excluding leading chars """
#    for i,c in enumerate(str):
#        if c in lead: continue
#        break
#    return str[:i]+str[i:].capitalize()

""" braille unicode chars ordered """
_brailleUnicode = [
'',         #00
u'\u2801',u'\u2803',u'\u2809',u'\u2819',u'\u2811',u'\u280b',u'\u281b',u'\u2813',u'\u280a',u'\u281a',
u'\u2805',u'\u2807',u'\u280d',u'\u281d',u'\u2815',u'\u280f',u'\u281f',u'\u2817',u'\u280e',u'\u281e',
u'\u2825',u'\u2827',u'\u282d',u'\u283d',u'\u2835',u'\u282f',u'\u283f',u'\u2837',u'\u282e',u'\u283e',
u'\u2821',u'\u2823',u'\u2829',u'\u2839',u'\u2831',u'\u282b',u'\u283b',u'\u2833',u'\u282a',u'\u283a',
u'\u2802',u'\u2806',u'\u2812',u'\u2832',u'\u2822',u'\u2816',u'\u2836',u'\u2826',u'\u2814',u'\u2834',
u'\u280c',u'\u282c',u'\u283c',u'\u281c',u'\u2804',u'\u2824',
u'\u2808',u'\u2818',u'\u2838',u'\u2810',u'\u2828',u'\u2830',u'\u2820',
u'\u2800',  #64
u'\n',      #65
]

def get_btext(text):
    """ return braille text (0102...) from unicode """
    return ''.join(['%02d' % _brailleUnicode.index(i) for i in text])

def get_text(btext):
    """ return unicode from braille text (0102...) """
    bt = [int(btext[i-1] + v) for i,v in enumerate(btext) if i%2]
    return ''.join([_brailleUnicode[i] for i in bt])

def get_braille_entities():
    """ return braille character entities """
    ent = {}
    for c in _brailleUnicode:
        if not c: continue
        n = ord(c)
        if n > 127 or c == '\n':
            ent[c] = '&#' + hex(n)[1:] + ';'
    return ent

def inst_or_ref(item, *xs):
    """ return isistance for the item or its reference """
    if hasattr(item, 'get_ref'):
        return isinstance(item.get_ref(), xs)
    return isinstance(item, xs)

#-------------------------------------------------------------------------------
# properties
class _NamedEnumerator(object):
    __slots__ = ['_v', '_dict', '_default']
##    def __new__(cls, v=None, d=None, default=None):
##        if v is None:
##            return None
##        return super(_NamedEnumerator, cls).__new__(cls)

    def __init__(self, v, d, default):
        self._dict = d
        self._default = default
        self.set(v)

    def __getstate__(self): return self._v, self._dict, self._default
    def __setstate__(self, tup): self._v, self._dict, self._default = tup

    def __int__(self):
        return self._v

    def __str__(self):
        return self._dict[self._v]

    def __eq__(self, other):
        if other in self._dict: return self._v == other
        if other == None: return self._v == self._default
        return str(self) == str(other)

    def __ne__(self, other):
        return not self.__eq__(other)

    def __nonzero__( self):
        return self._v != self._default

    def get(self):
        return self._v2

    def set(self, v):
        if v in self._dict.keys():
            self._v = v
        else:
            self._v = self._default
            for i,value in self._dict.iteritems():
                if v == value:
                    self._v = i
                    break


class _Up_dn(_NamedEnumerator):
    """ up down class: -1=down, 0=None, 1=up """
    def __init__(self, v):
        _NamedEnumerator.__init__(self, v, {0:'',1:'up',-1:'down'}, 0)


class _Above_below(_NamedEnumerator):
    """ above below class: -1=below, 0=None, 1=above """
    def __init__(self, v):
        _NamedEnumerator.__init__(self, v, {0:'',1:'above',-1:'below'}, 0)

class _Line_style(_NamedEnumerator):
    """ line style class: 0=None, 1=solid, 2=dashed """
    def __init__(self, v):
        _NamedEnumerator.__init__(self, v, {0:'',1:'solid',2:'dashed'}, 0)


class _Start_stop(_NamedEnumerator):
    """ start stop class: 0=None, 1=start 2=stop """
    def __init__(self, v):
        _NamedEnumerator.__init__(self, v, {0:'',1:'start',2:'stop'}, 0)


class _Start_stop_continue(_NamedEnumerator):
    """ start stop continue class: 0=None, 1=start 2=stop 3=continue """
    def __init__(self, v):
        _NamedEnumerator.__init__(self, v,
            {0:'',1:'start',2:'stop',3:'continue'}, 0)


class _Left_right(_NamedEnumerator):
    """ start stop class: 0=None, -1=left 1=right """
    def __init__(self, v):
        _NamedEnumerator.__init__(self, v, {0:'',-1:'left',1:'right'}, 0)


class _True_false(_NamedEnumerator):
    """ true false class: 0=false, 1=true """
    def __init__(self, v):
        if v == True: v = 1
        elif v == False: v = 0
        elif hasattr(v, 'lower'): v = v.lower()  #accept 'True' and 'False'
        _NamedEnumerator.__init__(self, v, {0:'false',1:'true'}, 0)


class _Tuple(tuple):
    """ tuple that can be initialized with a string and is represented as a string
        example:
            >>> x = _Tuplet('1,a')
            >>> tuple(x)
            ('1', 'a')
            >>> str(x)
            '1,2'
            >>> x = _Tuple('1')
            >>> x
            ('1',)
            >>> str(x)
            '1'
    """
    def __new__(cls, values):
        if values is None:
            #return tuple.__new__(cls, ()) #empty value
            return None
        elif isinstance(values, basestring):
            return tuple.__new__(cls, (v for v in values.split(',')))
        else:
            try:
                return tuple.__new__(cls, (v for v in values))
            except:
                return tuple.__new__(cls, (values,))

    #def __str__(self):
    def __repr__(self):
        #return tuple.__str__(self)[1:-1].replace(' ','')
        return ','.join((str(i) for i in self))


class _Tuple_int(tuple):
    """ tuple of integers that can be initialized with a string
        example:
            >>> x = _Tuple_int('1,2')
            >>> tuple(x)
            (1, 2)
            >>> str(x)
            '1,2'
            >>> x = _Tuple_int('1')
            >>> x
            (1,)
            >>> str(x)
            '1'
    """
    def __new__(cls, values):
        if values is None:
            #return tuple.__new__(cls, ()) #empty value
            return None
        elif isinstance(values, basestring):
            return tuple.__new__(cls, (int(v) for v in values.split(',')))
        else:
            try:
                return tuple.__new__(cls, (int(v) for v in values))
            except:
                return tuple.__new__(cls, (int(values),))

    #def __str__(self):
    def __repr__(self):
        #return tuple.__str__(self)[1:-1].replace(' ','')
        return ','.join((str(i) for i in self))


class _Tuple_tuple(tuple):
    """ tuple of tuples that can be initialized with a string
        separators are ; , + (see examples)
        example:
            >>> _Tuple_tuple('0')
            ((0,),)
            >>> _Tuple_tuple(0)
            ((0,),)
            >>> _Tuple_tuple('1')
            ((1,),)
            >>> _Tuple_tuple(1)
            ((1,),)
            >>> _Tuple_tuple('1,2')
            ((1, 2),)
            >>> _Tuple_tuple((1,2))
            ((1, 2),)
            >>> _Tuple_tuple('1,2;3,4')
            ((1, 2), (3, 4))
            >>> _Tuple_tuple(((1,2),(3,4)))
            ((1, 2), (3, 4))
            >>> _Tuple_tuple('1+2,3;4,5')
            (((1, 2), 3), (4, 5))
            >>> _Tuple_tuple((((1,2),3),(4,5)))
            (((1, 2), 3), (4, 5))
    """
    def __new__(cls, values):
        if not values:
            #try:
            #    return tuple.__new__(cls, ((int(values),),))  #0 -> (0,)
            #except:
            #    return tuple.__new__(cls, tuple((tuple(),))) #empty value
            return None
        elif isinstance(values, basestring):
            ls = []
            for v in values.split(';'):
                t = []
                for vv in v.split(','):
                    n = [int(i) for i in vv.split('+')]
                    if len(n) > 1:
                        t.append(tuple(n))
                    elif n:
                        t.append(n[0])
                #if len(t) > 1:
                ls.append(tuple(t))
                #elif t:
                #    ls.append(t[0])
            return tuple.__new__(cls, ls)
        else:
            try:
                it = iter(values)
                try:
                    return tuple.__new__(cls, (tuple(v) for v in it))
                except:
                    return tuple.__new__(cls, (values,))
            except:
                return tuple.__new__(cls, ((int(values),),))

    #def __repr__(self):
    #    return tuple.__repr__(self)[1:-1]
    def __str__(self):
        ret = []
        for t in self:
            ls = []
            for i in t:
                if isinstance(i, tuple):
                    ls.append(str(i)[1:-1].replace(',','+'))
                else:
                    ls.append(str(i))
            ret.append(','.join(ls))
        return ';'.join(ret).replace(' ','')

#-------------------------------------------------------------------------------
# xml id generator
default_id_prefix = 'bmml-'
default_id_format = default_id_prefix+'%04d'
def _xml_id(start=1, format=default_id_format):
    """ xml id generator """
    xml_id = start
    while True:
        yield format % xml_id
        xml_id += 1

_id_iterator = None
def init_xml_id(start=1):
    """ init the xml id generator """
    global _id_iterator
    _id_iterator = _xml_id(start)

def new_xml_id():
    """ generate a new _xml_id value """
    global _id_iterator
    if not _id_iterator:
        init_xml_id(1)
    return _id_iterator.next()

default_id_format_part = default_id_prefix+'p%02d'
_id_iterator_part = None  #for parts
def init_xml_id_part(start=1):
    """ init the xml id generator for parts """
    global _id_iterator_part
    _id_iterator_part = _xml_id(start, format=default_id_format_part)

def new_xml_id_part():
    """ generate a new _xml_id value for parts """
    global _id_iterator_part
    if not _id_iterator_part:
        init_xml_id_part(1)
    return _id_iterator_part.next()

#-------------------------------------------------------------------------------
# id_ normalizer
def normalize_ids(item, start_id=1, start_part_id=1):
    """sets the id values starting from start_id for item and children
       if some ids are reference outside item scope, references are not changed
       Restart the id and the id_part generators: backup them if needed
    """
    init_xml_id(start_id)
    init_xml_id_part(start_part_id)
    references = {}
    start_references = {}
    #.#reserved_ids = []
    old_ids = {}
    old_part_ids = {}
    stack = [item]
    while stack:
        e = stack.pop()
        if isinstance(e, _ElementProxy):
            if e.ref_id_ not in references:
                references[e.ref_id_] = []
            references[e.ref_id_].append(e)
            if hasattr(e, 'start_ref'):
                if e.start_ref not in start_references:
                    start_references[e.start_ref] = []
                start_references[e.start_ref].append(e)
        #.#elif isinstance(e, (Part, Part_data)):
        #.#    if e.id_ not in reserved_ids:
        #.#        reserved_ids.append(e.id_)
        elif isinstance(e, Part_data):
            new_id = new_xml_id_part()
            old_part_ids[e.id_] = new_id
            e.id_ = new_id
        elif isinstance(e, Part):
            new_id = old_part_ids[e.id_]
            e.id_ = new_id
        elif hasattr(e, 'id_'):
            new_id = new_xml_id()
            #.#while new_id in reserved_ids:
            #.#    new_id = new_xml_id()
            old_ids[e.id_] = new_id
            e.id_ = new_id
        if hasattr(e, '_is_container') and e._is_container:
            stack.extend(reversed(e))

    #change value to references
    for id_,items in references.iteritems():
        if not id_ in old_ids:
            continue
        new_id = old_ids[id_]
        for e in items:
            e.ref_id_ = new_id

    #change value to start_references
    for id_,items in start_references.iteritems():
        if not id_ in old_ids:
            continue
        new_id = old_ids[id_]
        for e in items:
            e.start_ref = new_id

    #set id generator
    #.#new_id = new_xml_id()
    #.#while new_id in reserved_ids:
    #.#    new_id = new_xml_id()

    #set part id generator
    #.#init_xml_id_part()
    #.#new_id_part = new_xml_id_part()
    #.#while new_id_part in reserved_ids:
    #.#    new_id_part = new_xml_id_part()

#-------------------------------------------------------------------------------
# element basics
class _Element(object):
    """ base element for elements that have no children and no
        text content.
            _req_attrs: required attributes
            _attrs: other attributes
    """
    _req_attrs = []
    _attrs = []
    _doc_element = False  #this element has not a doc representation
    _is_container = False
    _is_text = False

    def __init__(self, id_=None):
        if 'id_' in self._req_attrs:
            #self.id_ = id_ if id_ is not None else new_xml_id()
            if id_ is not None:
                self.id_ = id_
            elif isinstance(self, (Part, Part_data)):
                self.id_ = new_xml_id_part()
            else:
                self.id_ = new_xml_id()

    #def is_container(self):
    #    """ return True if is an _ElementContainer """
    #    return self._is_container

    #def is_text(self):
    #    """ return True if is an _ElementText """
    #    return self._is_text

    def get_text(self):
        """ return an empty string since there's no text for this element """
        return ''

    def get_textlen(self):
        """ return len of the text """
        return 0

    #def is_doc_element(self):
    #    return self._doc_element

    def xml_name(self):
        """ name used in xml """
        return self.__class__.__name__.lower()


class _ElementContainer(_Element):
    """ base element class for elements that contain other elements
        and have no text content.
            _elements: child elements that have only one occurence
            _elements_ls: child elements that can have more than one occurence
            _doc_element = True: this elemetn have a textual representation. The
                parameter can be changed on subclasses, i.e. containers that
                have no textual representation like Score_header
    """
    _elements = []
    _elements_ls = []
    _doc_element = True  #this element has a doc representation (changed on class basis, example Score_header)
    _is_container = True

    def __init__(self, id_=None):
        _Element.__init__(self, id_)
        self.__items = []
        #use-dict#self.__items_dict = {}

    #update item dict
    def _update_items_dict(self, item, delete=False):
        name = item.xml_name()
        if delete:
            if name in self.__items_dict:
                self.__items_dict[name].remove(item)
                if not self.__items_dict[name]:
                    del self.__items_dict[name]
        else:
            if name not in self.__items_dict:
                self.__items_dict[name] = [item]
            else:
                self.__items_dict[name].append(item)

    #sequence protocol
    def __iter__(self):
        return iter(self.__items)

    # commented. Use get_nchildren() ==> to be removed
    def __len__(self):
        return len(self.__items)

    def __getitem__(self, index):
        return self.__items[index]

    def __setitem__(self, index, value):
        self.__items[index] = value
        #use-dict#self._update_items_dict(value)

    def __delitem__(self, index):
        #use-dict#value = self.__items[index]
        #use-dict#self._update_items_dict(value, delete=True)
        del self.__items[index]

    def __nonzero__(self):
        import inspect
        print '__nonzero__ called for %s' % self
        try:
            for frame,fname,number,func,lines,index in inspect.stack()[1:]:
                if lines:
                    print '\t%s:%s\n\t\t%s' % (fname,number,lines[index])
                else:
                    print '\t%s:%s' % (fname,number)
        except:
            pass
        return len(self)>0

    def iter_textelements(self):
        """ custom iterator to skip elements that return no text """
        if self._doc_element:
            for item in self:
                if item._doc_element:
                    yield item
        raise StopIteration

    def get_text(self):
        """ return the text of child elements """
        ls = []
        for i in self.iter_textelements():
            ls.append(i.get_text())
        return ''.join(ls)

    def get_textlen(self):
        """ return len of the text """
        return sum((i.get_textlen() for i in self.iter_textelements()))

    def _set_element(self, name, item, index=None):
        """ set an element that have only one occurence
                name: name of the element
                item: the item to set
                index=None: optional index for insertion in a given position
        """
        if item.xml_name() != name:
            raise ValueError, '_set_element: class name = %s but passed name %s'\
                % (item.xml_name(), name)
        d = self._get_element(name)
        if d != None:
            self.__items.remove(d)
        if index is not None:
            self.__items.insert(index, item)
        else:
            self.__items.append(item)
        #use-dict#self._update_items_dict(item)  #non tiene conto dell'inserimento, da rifare

    def _get_element(self, name):
        """ get an element that have only one occurence
                name: name of the element
        """
        items = [d for d in self.__items if d.xml_name() == name]
        if not items: return None
        return items[0]
        #use-dict#if self.__items_dict.has_key(name):
        #use-dict#    return self.__items_dict[name][0]
        #use-dict#return None

    def _get_element_ls(self, name):
        """ get a list of elements that can have more than one occurence
                name: name of the element
        """
        items = [d for d in self.__items if d.xml_name() == name]
        return items
        #use-dict#if self.__items_dict.has_key(name):
        #use-dict#    return self.__items_dict[name]
        #use-dict#return []

    def _add_element(self, name, item, index=None):
        """ add an element that can have more than one occurence
                name: name of the element
                item: the item to add
        """
        if item.xml_name() != name:
            raise ValueError, '_add_element: class name = %s but passed name %s'\
                % (item.xml_name(), name)
        if index is not None:
            self.__items.insert(index, item)
        else:
            self.__items.append(item)
        #use-dict#self._update_items_dict(item)  #non tiene conto dell'inserimento, da rifare

    def _extend_element(self, name, items):
        """ extend for elements that can have more than one occurence
                name: name of the element
                items: the items to add
        """
        for item in items:
            self._add_element(name, item)
            #use-dict#self._update_items_dict(item)

    def _del_element(self, name, item=None):
        """ delete an element
                name: name of the element
                item=None: optional item to be deleted. If None it will be
                    retrieved based on the name value
        """
        if item is None:
            items = self._get_element_ls(name)
            if len(items) > 1:
                raise ValueError, '_del_element: more then one item with name %s' %name
            item = items[0]
        elif item.xml_name() != name:
            raise ValueError, '_del_element: class name = %s but passed name %s'\
                % (item.xml_name(), name)
        self.__items.remove(item)
        #use-dict#self._update_items_dict(item, delete=True)

    def _insert_element(self, name, item, next_item=None):
        """ insert an element
                name: name of the element
                item: item to be inserted
                next_item: item past the insertion point. If None insertion will
                    be at the end
        """
        if item == None: return
        if item.xml_name() != name:
            raise ValueError, '_insert_element: class name = %s but passed name %s'\
                % (item.xml_name(), name)
        if next_item != None:
#            if next_item.xml_name() != name:
#                raise ValueError, '_insert_element: class name = %s but passed name %s'\
#                    % (next_item.xml_name(), name)
            i = self.__items.index(next_item)
        else:
            i = len(self.__items)
        self.__items.insert(i, item)
        #use-dict#self._update_items_dict(item)  #non tiene conto dell'inserimento, da rifare

    def get_nchildren(self):
        """ return the number of children """
        return len(self.__items)

    def index(self, item):
        """ return the index of an element """
        return self.__items.index(item)

    def append(self, item):
        """ add or set a generic element """
        name = item.xml_name()
        try:
            f = getattr(self, 'add_'+name)
        except AttributeError:
            f = getattr(self, 'set_'+name)
        f(item)

    def extend(self, items):
        """ add or set a elements from list """
        for item in items:
            self.append(item)

    def insert(self, index, item):
        """ insert a generic element at index """
        name = item.xml_name()
        f = getattr(self, 'insert_'+name)
        if 0 <= index < len(self.__items):
            next_item = self.__items[index]
        else:
            next_item = None
        f(item, next_item)

    def remove(self, item):
        """ remove a generic element """
        name = item.xml_name()
        f = getattr(self, 'del_'+name)
        if hasattr(self, 'set_'+name):
            f()
        else:
            f(item)

##    def __getattr__(self, name):
##        """ return function corresponding to name
##                example:
##                    name = 'get_note'
##                    return self._get_element('note')
##        """
##        try:
##            return super(_ElementContainer, self).__getattr__(name)
##        except:
##            f = None
##            if name.startswith('get_'):
##                fname = name[4:]
##                if fname in self._elements:
##                    f = self._get_element
##                elif fname in self._elements_ls:
##                    f = self._get_element_ls
##            elif name.startswith('set_'):
##                fname = name[4:]
##                if fname in self._elements:
##                    f = self._set_element
##            elif name.startswith('add_'):
##                fname = name[4:]
##                if fname in self._elements_ls:
##                    f = self._add_element
##            elif name.startswith('del_'):
##                fname = name[4:]
##                if fname in self._elements or fname in self._elements_ls:
##                    f = self._del_element
##            elif name.startswith('insert_'):
##                fname = name[7:]
##                #if fname in self._elements_ls:
##                if fname in self._elements or fname in self._elements_ls:
##                    f = self._insert_element
##            elif name.startswith('extend_'):
##                fname = name[7:]
##                if fname in self._elements_ls:
##                    f = self._extend_element
##
##            if f:
##                import inspect
##                print '__getattr__ called with name=%s' % name
##                try:
##                    for frame,fname,number,func,lines,index in inspect.stack()[1:]:
##                        print '\t%s:%s\n\t\t%s' % (fname,number,lines[index])
##                except:
##                    pass
##
##                return lambda *args, **kwargs: f(fname, *args, **kwargs)
##
##            raise AttributeError('%s instance has no attribute \'%s\'' % (self.__class__.__name__, name))


class _ElementText(_Element):
    """ base element class for elements that have a text content """
    _doc_element = True  #this element has a doc representation
    _is_text = True

    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
        _Element.__init__(self, id_)
        self.text = text    #text as unicode characters

    def set_text(self, text):
        self._text = text
        self.textlen = len(text)

    def get_text(self):
        return self._text

    text = property(get_text, set_text)

    def get_textlen(self):
        """ return len of the text """
        return self.textlen



class _ElementValue(_Element):
    """ base element class with value as content in the XML """
    #def __init__(self, id_=None, value=None):
    #    _Element.__init__(self, id_)
    def __init__(self, value=None):
        _Element.__init__(self)
        self._value = value
    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = value
    value = property(_get_value, _set_value)


class _ElementProxy(object):
    """ proxy element for handling references """
    _req_attrs = ['id_']
    _attrs = []
    _doc_element = False  #this element has not a doc representation

    def __init__(self, ref_obj=None, ref_id_=None):
        if ref_obj is None and ref_id_ is None:
            raise ValueError('_ElementProxy.__init__ need at least an object or an id_ reference')
        self.bind(ref_obj)  #direct binding to object
        self.ref_id_ = ref_id_  #assign an id_ value for binding only through id_

    #deepcopy for this object is ambiguous
    def __deepcopy__(self, memo):
##        import inspect
##        print '__deepcopy__ called for %s' % self
##        try:
##            for frame,fname,number,func,lines,index in inspect.stack()[1:]:
##                if lines:
##                    print '\t%s:%s\n\t\t%s' % (fname,number,lines[index])
##                else:
##                    print '\t%s:%s' % (fname,number)
##        except:
##            pass
        #return copy.copy(self)
        ret = copy.copy(self)
        ret._ref = self._ref  #set the reference to the previous object
        return ret

    def bind(self, ref_obj):
        if ref_obj is None:
            self._ref = None
        elif isinstance(ref_obj, weakref.ProxyTypes):
            self._ref = ref_obj
        else:
            self._ref = weakref.proxy(ref_obj)

    def isbound(self):
        try:
            #return self._ref is not None
            return self._ref is not None and hasattr(self._ref, 'id_')
        except ReferenceError:
            return False

    def get_ref(self):
        if self.isbound():
            return self._ref
        raise ReferenceError('%s is not bound' % self.xml_name())

    def __getattr__(self, name):
        if name.startswith('_'): #private attributes
            raise AttributeError('%s not found' % name)
        if name == 'id_':
            if self.isbound() and hasattr(self._ref, 'id_'):
                return self._ref.id_
            return self.ref_id_
        if not self.isbound():
            try:
                return super(_ElementProxy, self).__getattr__(name)
            except:
                raise AttributeError('%s is not bound' % self.xml_name())
        return getattr(self._ref, name)

    def xml_name(self):
        """ name used in xml """
        return self.__class__.__name__.lower()

#-------------------------------------------------------------------------------
# iterators
class _Sort_iterator(object):
    """ iterator on sorted element """
    def __init__(self, element):
        self.iter = iter(element.sort())
    def next(self):
        return self.iter.next()

#-------------------------------------------------------------------------------
# BMML classes in alphabetic order
class Abbr_name(_ElementText):
    """
    Abbreviated name, child of L{Part_data}

    DTD definition::
        <!ELEMENT abbr_name (#PCDATA)>
        <!ATTLIST abbr_name
            %id;
            value CDATA     #IMPLIED>

    It's the abbreviated version
    of the L{Name} element. C{value} is the unicode text used for converting to
    other format, as MusicXML.

    @todo: move lang from part_data into this element.
    """
    _req_attrs = ['id_']
    _attrs = ['value']
    def __init__(self, id_, text, value=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: unicode text
        """
        _ElementText.__init__(self, id_, text)
        self.value = value  #text in ink (unicode)


class Accidental(_ElementText):
    """
    Accidental, child of L{Note}

    DTD definition::
        <!ELEMENT accidental (#PCDATA)>
        <!ATTLIST accidental
            %id;
            value CDATA         #REQUIRED
            cancel CDATA        #IMPLIED
            placement (above|below)     #IMPLIED
            step CDATA          #IMPLIED
            editorial CDATA     #IMPLIED>

    C{value} can range from -2 to 2, with -2 equals to double flat and 2 equals
    to double sharp. If there are one or two naturals before the accidental sign
    the C{cancel} attribute is used, ranging from 0 to 2. A special case is when
    one or two naturals are in front of the note: in this case a C{value} is 0
    and C{cancel} is 1 or 2.

    C{placement} possible values are I{above, below}. Note that in Braille
    music there's no distinction and the dots 6 is always used.
    C{step} possible values are I{1/4, 3/4}.
    C{editorial} is the dots 5 in Braille and possible values are I{braille,
    parenthesis}.
    Usually the braille value is used but it can be parenthesis if we want to
    render it as parenthesis when converting to another format.

    @todo: change C{step} and C{editorial} from CDATA to proper value.
    """
    _req_attrs = ['id_','value']
    _attrs = ['cancel','placement','step','editorial']
    def __init__(self, id_, text, value, cancel=None, placement=None, step=None, editorial=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int} from -2 to 2
        @param cancel: C{int} from 0 to 2
            number of naturals
        @param placement: C{string} in ['above', 'below']
        @param step: C{string} in ['1/4', '3/4']
        @param editorial:  C{string} in ['braille', 'parenthesis']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value      #int -2...+2
        self.cancel = cancel    #int   0...2
        self.placement = placement  #above-below
        self.step = step        #1/4, 3/4
        self.editorial = editorial    #braille,parenthesis

    def _get_placement(self):
        return self._placement
    def _set_placement(self, value):
        self._placement = _Above_below(value)
    placement = property(_get_placement, _set_placement)

    def _get_step(self):
        return self._step
    def _set_step(self, value):
        self._step = _NamedEnumerator(value, {0:'',1:'1/4',2:'3/4'}, 0)
    step = property(_get_step, _set_step)

    def _get_editorial(self):
        return self._editorial
    def _set_editorial(self, value):
        self._editorial = _NamedEnumerator(value, {0:'',
            1:'braille',2:'parenthesis'}, 0)
    editorial = property(_get_editorial, _set_editorial)


class Accordion_register(_ElementText):
    """
    Accordion register, child of L{Part}

    DTD definition::
        <!ELEMENT accordion_register (#PCDATA)>
        <!ATTLIST accordion_register
            %id;
            value CDATA     #REQUIRED
            tremolo (normal|double|high|low|high_low)  #IMPLIED>

    C{value} can be a single integer value, 2,4,8 or 16 or a list of integers,
    example "4" or "4,8".
    C{tremolo} can be normal (two dots in the middle of the circle), double
    (three dots), high (a dot to the right), low (a dot to the left) or a
    combination of high and low (a dot to the right and a dot to the left).
    """
    _req_attrs = ['id_','value']
    _attrs = ['tremolo']
    def __init__(self, id_, text, value, tremolo=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: tuple of int (2,4,8 or 16)
        @param tremolo: C{string} in ['normal','double','high','low','high_low']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.tremolo = tremolo

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _Tuple_int(value)
    value = property(_get_value, _set_value)

    def _get_tremolo(self):
        return self._tremolo
    def _set_tremolo(self, value):
        self._tremolo = _NamedEnumerator(value, {0:'',
            1:'normal', 2:'double',3:'high',4:'low',5:'high_low',}, 0)
    tremolo = property(_get_tremolo, _set_tremolo)


class Accordion_row(_ElementText):
    """
    Accordion row, child of L{Note}, L{Interval}

    DTD definition::
        <!ELEMENT accordion_row (#PCDATA)>
        <!ATTLIST accordion_row
            %id;
            value CDATA             #REQUIRED>

    The C{value} ranges from 0 to 8.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int} ranging from 0 to 8
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #int


class Alteration(_ElementValue):
    """
    Alteration value, child of L{Note_data}

    DTD definition::
        <!ELEMENT alteration (#PCDATA)>

    The alteration value as calculated for this note, ranging from -2 to 2. This
    value comes from an alteration in the key signature, from an accidental
    written before this note or in the same measure.
    """
    pass


class Alternation(_ElementText):
    """
    Alternation, child of L{Note}

    DTD definition::
        <!ELEMENT alternation (#PCDATA)>
        <!ATTLIST alternation
            %id;
            value CDATA             #REQUIRED>

    The alternation C{value} ranges from 1 to 5 and is the number of beats
    notated. See NIM 7-6.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int} ranging from 0 to 5
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #int


class Alternation_ref(_ElementProxy):
    """
    Alternation reference, child of L{Note_data}

    DTD definition::
        <!ELEMENT alternation_ref EMPTY>
        <!ATTLIST alternation_ref
            %id_ref;
            type    (start|stop)   #REQUIRED>

    The alternation reference refers to the alternation element written for this
    note or for the previous one. The link with its referred is given by the
    C{id_ref} attribute.
    It's C{type} could be I{start} or I{stop}.
    """
    _req_attrs = ['id_','type_']
    def __init__(self, id_, type_):
        """
        @param id_: id
        @param type_: C{string} in ['start', 'stop']
        """
        _ElementProxy.__init__(self, ref_id_=id_)
        self.type_ = type_

    def _get_type_(self):
        return self._type_
    def _set_type_(self, value):
        self._type_ = _Start_stop(value)
    type_ = property(_get_type_, _set_type_)

    #def is_container(self):
    #    """ hide container """
    #    return False


class Appoggiatura_ref(_ElementProxy):
    """
    Appoggiatura reference, child of L{Note_data}

    DTD definition::
        <!ELEMENT appoggiatura_ref EMPTY>
        <!ATTLIST appoggiatura_ref
            %id_ref;>

    Refers to the appoggiatura element written for this note or for a previous
    one in case of doubling.
    The appoggiatura is written as an ornament and the C{id_ref} links to
    the L{Ornament_type} element.
    """
    _req_attrs = ['id_']
    def __init__(self, id_):
        """
        @param id_: id
        """
        _ElementProxy.__init__(self, ref_id_=id_)

    def _get_short(self):
        return self._ref.value == 'short_appoggiatura'
    short = property(_get_short)

    #def is_container(self):
    #    """ hide container """
    #    return False


class Barline(_ElementContainer):
    """
    Barline, child of L{Part}

    DTD definition::
        <!ELEMENT barline (fermata?,barline_type,fermata?)>
        <!ATTLIST barline
            %id;
            location (left|middle|right) #IMPLIED>

    C{location} indicates the barline position in the measure and defaults to
    right.
    """
    _req_attrs = ['id_']
    _attrs = ['location']
    _elements = ['barline_type']
    _elements_ls = ['fermata']
    def __init__(self, id_, location=None):
        """
        @param id_: id
        @param location: C{string} in ['left', 'middle', 'right']
        """
        _ElementContainer.__init__(self, id_)
        self.location = location

    def _get_location(self):
        return self._location
    def _set_location(self, value):
        self._location = _NamedEnumerator(value, {0:'',
            1:'right',2:'middle',3:'left'}, 0)
    location = property(_get_location, _set_location)

    def get_barline_type(self):
        return self._get_element('barline_type')
    def set_barline_type(self, item):
        self._set_element('barline_type', item)
    #def insert_barline_type(self, item, next_item=None):
    #   self._insert_element('barline_type', item, next_item)
    def del_barline_type(self):
        self._del_element('barline_type')

    def get_fermata(self):
        return self._get_element_ls('fermata')
    def add_fermata(self, item, index=None):
        self._add_element('fermata', item, index)
    def insert_fermata(self, item, next_item=None):
        self._insert_element('fermata', item, next_item)
    def del_fermata(self, item):
        self._del_element('fermata', item)
    def extend_fermata(self, items):
        self._extend_element('fermata', items)

    #helper function
    def _get_value(self):
        return self.get_barline_type().value
    value = property(_get_value)


class Barline_type(_ElementText):
    """
    Barline_type, child of L{Barline}

    DTD definition::
        <!ELEMENT barline_type (#PCDATA)>
        <!ATTLIST barline_type
            %id;
            value CDATA         #REQUIRED>

    C{value} is the type of barline and it's used in conversion to other
    formats. Can be one of I{space, newline, braille, dotted,
    light_heavy, light_light, dots_light_heavy} or another value.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['space', 'newline', 'braille', 'dotted',
            'light_heavy', 'light_light', 'dots_light_heavy', 'heavy_light_dots']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',
            1:'space',#64
            2:'newline',#65
            3:'braille',#641264 or 641265
            4:'dotted',#641164 or 641165
            5:'light_heavy',#3211
            6:'light_light',#321155
            7:'dots_light_heavy',#3242 or 32423211
            8:'heavy_light_dots',#3247
            }, 0)
    value = property(_get_value, _set_value)


class Barre(_ElementText):
    """
    Barre, child of L{Part}

    DTD definition::
        <!ELEMENT barre (#PCDATA)>
        <!ATTLIST barre
            %id;
            value (full|half|vertical)    #REQUIRED>
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['full', 'half', 'vertical']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',
            1:'full',2:'half',3:'vertical',
            }, 0)
    value = property(_get_value, _set_value)


class Bow(_ElementText):
    """
    Bow, child of L{Note}

    DTD definition::
        <!ELEMENT bow (#PCDATA)>
        <!ATTLIST bow
            %id;
            value (up|down) #REQUIRED
            doubled (true|false)    #IMPLIED>
    """
    _req_attrs = ['id_','value']
    _attrs = ['doubled']
    def __init__(self, id_, text, value, doubled=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['up','down']
        @param doubled: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.doubled = doubled

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _Up_dn(value)
    value = property(_get_value, _set_value)

    def _get_doubled(self):
        return self._doubled
    def _set_doubled(self, value):
        self._doubled = _True_false(value)
    doubled = property(_get_doubled, _set_doubled)


class Breath(_ElementText):
    """
    Breath, child of L{Part}

    DTD definition::
        <!ELEMENT breath (#PCDATA)>
        <!ATTLIST breath
            %id;
            value (full|half|caesura)    #REQUIRED>
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['full', 'half', 'caesura']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',
            1:'full',2:'half',3:'caesura',
            }, 0)
    value = property(_get_value, _set_value)


class Chord(_ElementContainer):
    """
    Chord symbol, child of L{Score_data}, L{Part}

    DTD definition::
        <!ELEMENT chord (chord_data,chord_type,(stem_type,dot?)?)>
        <!ATTLIST chord
            %id;>

    Chord symbols can be written in at least three ways: below the lyric or the
    music, inside a chord part, inside a part after a L{Chord_prefix}.
    """
    _req_attrs = ['id_']
    #_elements = ['chord_data','chord_type','stem_type','dot']
    _elements = ['chord_data','chord_type']

    def __init__(self, id_):
        """
        @param id_: id
        """
        _ElementContainer.__init__(self, id_)
        self.data = None

    def __iter__(self):
        yield self.get_chord_data()
        yield self.get_chord_type()
        for item in self._elements[2:]:
            v = getattr(self, 'get_'+item)()
            if v is not None:
                yield v

    def get_chord_data(self):
        return self._get_element('chord_data')
    def set_chord_data(self, item):
        if item is not None:
            self._set_element('chord_data', item)
        self._data = item
    #def insert_chord_data(self, item, next_item=None):
    #   self._insert_element('chord_data', item, next_item)
    def del_chord_data(self):
        self._del_element('chord_data')
    #def set_chord_data(self, value):
    #    if value is not None:
    #        super(Chord, self).__getattr__('set_chord_data')(value)
    #    self._data = value
    data = property(lambda self: self._data, set_chord_data)

    def get_chord_type(self):
        return self._get_element('chord_type')
    def set_chord_type(self, item):
        self._set_element('chord_type', item)
    #def insert_chord_type(self, item, next_item=None):
    #   self._insert_element('chord_type', item, next_item)
    def del_chord_type(self):
        self._del_element('chord_type')

##    def get_stem_type(self):
##        return self._get_element('stem_type')
##    def set_stem_type(self, item):
##        self._set_element('stem_type', item)
##    #def insert_stem_type(self, item, next_item=None):
##    #   self._insert_element('stem_type', item, next_item)
##    def del_stem_type(self):
##        self._del_element('stem_type')
##
##    def get_dot(self):
##        return self._get_element('dot')
##    def set_dot(self, item):
##        self._set_element('dot', item)
##    #def insert_dot(self, item, next_item=None):
##    #   self._insert_element('dot', item, next_item)
##    def del_dot(self):
##        self._del_element('dot')


class Chord_data(_ElementContainer):
    """
    Chord data, child of L{Chord}

    DTD definition::
        <!ELEMENT chord_data (duration)>

    The L{duration} value is the only calculated value for this chord.
    It's value can be calculated from L{Chord_type} or L{Stem}.
    """
    _elements = ['duration']
    _doc_element = False  #this element has not a doc representation
    #def __init__(self):
    #    _ElementContainer.__init__(self)

    def get_duration(self):
        return self._get_element('duration')
    def set_duration(self, item):
        self._set_element('duration', item)
    #def insert_duration(self, item, next_item=None):
    #   self._insert_element('duration', item, next_item)
    def del_duration(self):
        self._del_element('duration')

    def _get_duration(self):
        return self.get_duration().value
    duration = property(_get_duration,
        doc='integer value with quarter=1024')


class Chord_prefix(_ElementText):
    """
    Chord prefix, child of L{Chord}

    DTD definition::
        <!ELEMENT chord_prefix (#PCDATA)>
        <!ATTLIST chord_prefix
            %id;>

    Prefix for chord symbols after the notes in a part. See Vassio.
    """
    _req_attrs = ['id_']
    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
        _ElementText.__init__(self, id_, text)


class Chord_type(_ElementText):
    """
    Chord type, child of L{Chord}

    DTD definition::
        <!ELEMENT chord_type (#PCDATA)>
        <!ATTLIST chord_type
            %id;
            root   CDATA        #REQUIRED
            notes  CDATA        #REQUIRED
            bass   CDATA        #IMPLIED
            duration   CDATA    #IMPLIED
            dot    CDATA        #IMPLIED
            value  CDATA        #IMPLIED>

    Chord symbol element that can be written in Braille as a note or as letter,
    preceded and followed by other Braille symbols.

    C{root} and C{bass} are a string composed by the note
    name, ranging from I{A} to I{B}, eventually followed by the alteration
    written as I{#} or I{b}, example "C#" or "Bb".

    C{notes} are the notes that build the chord, including the optional bass and
    the root. Notes are written as a sequence separated by commas, example
    "C,E,G" or "C,Eb,G".

    C{duration} is expressed as 1024 for a quarter. C{dot} is the number of dots
    for this chord, usually one. C{duration} and C{dot} are optional parameter
    and are used when the chord symbol is written as a note.

    C{value} is the text used in conversion to other formats, example "Cmin"
    """
    _req_attrs = ['id_','root','notes']
    _attrs = ['bass','duration','dot','value']
    def __init__(self, id_, text, root, notes, bass=None, duration=None, dot=None, value=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param root: the root note, examples "C#" or "Bb"
        @param notes: the notes that builds the chord, examples "C,E,G" or
            "C,Eb,G"
        @param bass: the optional bass note written as the root
        @param duration: duration of the chord with 1024 for a quarter
        @param dot: number of dots, usually one
        @param value: unicode text for conversion, example "Cmin"
        """
        _ElementText.__init__(self, id_, text)
        self.root = root
        self.bass = bass
        self.notes = notes #string with notes (in C) example: C,Eb,G
        self.duration = duration  #duration if written in the string
        self.dot = dot  #dot if written
        self.value = value

    def _get_root(self):
        return self._root
    def _set_root(self, value):
        self._root = _NamedEnumerator(value, {-1:'',
            0:'C',1:'D',2:'E',3:'F',4:'G',5:'A',6:'B',
            10:'C#',11:'D#',12:'E#',13:'F#',14:'G#',15:'A#',16:'B#',
            20:'Cb',21:'Db',22:'Eb',23:'Fb',24:'Gb',25:'Ab',26:'Bb',
            30:'C##',31:'D##',32:'E##',33:'F##',34:'G##',35:'A##',36:'B##',
            40:'Cbb',41:'Dbb',42:'Ebb',43:'Fbb',44:'Gbb',45:'Abb',46:'Bbb',
            },-1)
    root = property(_get_root, _set_root)

    def _get_bass(self):
        return self._bass
    def _set_bass(self, value):
        self._bass = _NamedEnumerator(value, {-1:'',
            0:'C',1:'D',2:'E',3:'F',4:'G',5:'A',6:'B',
            10:'C#',11:'D#',12:'E#',13:'F#',14:'G#',15:'A#',16:'B#',
            20:'Cb',21:'Db',22:'Eb',23:'Fb',24:'Gb',25:'Ab',26:'Bb',
            30:'C##',31:'D##',32:'E##',33:'F##',34:'G##',35:'A##',36:'B##',
            40:'Cbb',41:'Dbb',42:'Ebb',43:'Fbb',44:'Gbb',45:'Abb',46:'Bbb',
            },-1)
    bass = property(_get_bass, _set_bass)


class Clef(_ElementText):
    """
    Clef, child of L{Part}

    DTD definition::
        <!ELEMENT clef (#PCDATA)>
        <!ATTLIST clef
            %id;
            name CDATA          #REQUIRED
            line CDATA          #IMPLIED
            eight (above|below) #IMPLIED
            cross_staff (true|false)    #IMPLIED
            >

    C{name} can be one of I{G, F, C}. Other values are possible for
    percussion or modern clefs (not handled in this version). C{line} is the
    line on which the clef is written. The default value is 2 for the G clef and
    4 for the F clef.

    C{eight} is the 8 written above or below the note. The C{cross_staff} flag
    is for the clefs that are used when one hand part is written in the opposite
    staff, see NIM 15-14.
    """
    _req_attrs = ['id_','name']
    _attrs = ['line','eight','cross_staff']
    def __init__(self, id_, text, name, line=None, eight=None, cross_staff=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param name: C{string} in ['G', 'F', 'C']
        @param line: C{int} from 0 to 5
        @param eight: C{string} in ['above', 'below']
        @param cross_staff: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.name = name    #G,F,C
        self.line = line    #int
        self.eight = eight  #above,below
        self.cross_staff = cross_staff  #None,True

    def _get_name(self):
        return self._name
    def _set_name(self, value):
        self._name = _NamedEnumerator(value, {0:'',1:'G',2:'C',3:'F'}, 0)
    name = property(_get_name, _set_name)

    def _get_eight(self):
        return self._eight
    def _set_eight(self, value):
        self._eight = _Above_below(value)
    eight = property(_get_eight, _set_eight)

    def _get_cross_staff(self):
        return self._cross_staff
    def _set_cross_staff(self, value):
        self._cross_staff = _True_false(value)
    cross_staff = property(_get_cross_staff, _set_cross_staff)


class Coda(_ElementText):
    """
    Coda, child of L{Part}

    DTD definition::
        <!ELEMENT coda (#PCDATA)>
        <!ATTLIST coda
            %id;>
    """
    _req_attrs = ['id_']
    def __init__(self, id_, text):
        """
        @param id_: id
        """
        _ElementText.__init__(self, id_, text)


class Dot(_ElementText):
    """
    Dot, child of L{Note}

    DTD definition::
        <!ELEMENT dot (#PCDATA)>
        <!ATTLIST dot
            %id;
            value CDATA             #REQUIRED>

    C{value} is the number of dots, from 1 to 3.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int} from 1 to 3
        """
        _ElementText.__init__(self, id_, text)
        self.value = value  #int 1...3


class Duration(_ElementValue):
    """
    Duration, child of L{Chord_data}, L{Note_data}, L{Rest_data}, L{Stem_data}

    DTD definition::
        <!ELEMENT duration (#PCDATA)>

    The duration as calculated for a musical element, with 1024 for a quarter.
    For dotted notes or rests the duration take into account also the dots, so
    a dotted eighth have duration equals to 768 (512+256). For musical elements
    in an irregular group the duration value is the duration as written, so
    three eights in a triplet have duration equals to 512. The real duration can
    be retrieved combining this value with the L{Tuplet_ref} data.
    """
    pass


class Dynamic(_ElementText):
    """
    Dynamic, child of L{Part}

    DTD definition::
        <!ELEMENT dynamic (#PCDATA)>
        <!ATTLIST dynamic
            %id;
            value CDATA         #REQUIRED
            line_of_continuation (1|2) #IMPLIED>

    C{value} can be one of::
        I{mp, mf, sf, sfp, sfz, sfpp, sffz,
        rf ,rfz ,f, p, cresc., dim.,
        ff,fff,ffff,fffff,ffffff,
        pp,ppp,pppp,ppppp,pppppp,
        accordion_draw, accordion_push,
        cresc_start, cresc_stop, dim_start, dim_stop}

    The I{crest_start, cresc_stop} values and so on are used for the Braille
    symbol for start crescendo and end crescendo.

    Other values are written as L{Generic_text}.
    """
    _req_attrs = ['id_','value']
    _attrs = ['line_of_continuation']
    def __init__(self, id_, text, value, line_of_continuation=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['mp', 'mf', 'sf', 'sfp', 'sfz', 'sfpp', 'sffz',
            'rf', 'rfz', 'f', 'p', 'cresc.', 'dim.',
            'ff', 'fff', 'ffff', 'fffff', 'ffffff',
            'pp', 'ppp', 'pppp', 'ppppp', 'pppppp',
            'accordion_draw', 'accordion_push',
            'cresc_start', 'cresc_stop', 'dim_start', 'dim_stop']
        @param line_of_continuation: 1 or 2
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.line_of_continuation = line_of_continuation

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',
            1:'mp',2:'mf',3:'sf',4:'sfp',5:'sfz',6:'sfpp',7:'sffz',
            8:'rf',9:'rfz',10:'f',11:'p',12:'cresc.',13:'dim.',
            14:'ff',15:'fff',16:'ffff',17:'fffff',18:'ffffff',
            19:'pp',20:'ppp',21:'pppp',22:'ppppp',23:'pppppp',
            30:'accordion_draw', 31:'accordion_push',
            40:'cresc_start',41:'cresc_stop',42:'dim_start',43:'dim_stop'
            }, 0)
    value = property(_get_value, _set_value)

    def _get_line_of_continuation(self):
        return self._line_of_continuation
    def _set_line_of_continuation(self, value):
        self._line_of_continuation = value
    line_of_continuation = property(_get_line_of_continuation,
        _set_line_of_continuation)


class Editorial_mark(_ElementText):
    """
    Editorial_mark, child of L{Rest}

    DTD definition::
        <!ELEMENT editorial_mark (#PCDATA)>
        <!ATTLIST editorial_mark
            %id;>
    """
    _req_attrs = ['id_']
    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
        _ElementText.__init__(self, id_, text)


class Ending(_ElementText):
    """
    Ending, child of L{Part}

    DTD definition::
        <!ELEMENT ending (#PCDATA)>
        <!ATTLIST ending
            %id;
            value CDATA         #REQUIRED>

    C{value} can be a single integer value or a list of integers,
    example "1" or "1,2"
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: tuple of ints
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #tuple of int

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _Tuple_int(value)
    value = property(_get_value, _set_value)


class Family(_ElementValue):
    """
    Family, child of L{Part_data}

    DTD definition::
        <!ELEMENT family (#PCDATA)>
        <!ATTLIST family
            %id;>

    Known values are I{brass, chords, keyboard, organ
    pedal, string, voice}.
    """


class Fermata(_ElementText):
    """
    Fermata, child of L{Part}, L{Note}, L{Rest}, L{Barline}

    DTD definition::
        <!ELEMENT fermata (#PCDATA)>
        <!ATTLIST fermata
            %id;
            shape CDATA #IMPLIED>

    The C{shape} attribute can be on of I{normal,square,tent} or other.
    """
    _req_attrs = ['id_']
    _attrs = ['shape']
    def __init__(self, id_, text, shape=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param shape: C{string} in ['normal','square','tent']
        """
        _ElementText.__init__(self, id_, text)
        self.shape = shape

    def _get_shape(self):
        return self._shape
    def _set_shape(self, value):
        self._shape = _NamedEnumerator(value, {0:'',
            1:'normal',2:'square',3:'tent',
            }, 0)
    shape = property(_get_shape, _set_shape)


class Fingering(_ElementText):
    """
    Fingering, child of L{Note}, L{Interval}

    DTD definition::
        <!ELEMENT fingering (#PCDATA)>
        <!ATTLIST fingering
            %id;
            value CDATA     #IMPLIED
            alternative CDATA     #IMPLIED>

    C{value} and C{alternative} range from 1 to 5. In case of a finger
    substitution on a note C{value} is written as a sequence of integers
    separated by comma, example "1,2". One of C{value} and C{alternative} is
    mandatory.
    """
    _req_attrs = ['id_']
    _attrs = ['value','alternative']
    def __init__(self, id_, text, value=None, alternative=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: tuple of ints
        @param alternative: tuple of ints
        """
        _ElementText.__init__(self, id_, text)
        self.value = value  #list of int
        self.alternative = alternative

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _Tuple_int(value)
    value = property(_get_value, _set_value)

    def _get_alternative(self):
        return self._alternative
    def _set_alternative(self, value):
        self._alternative = _Tuple_int(value)
    alternative = property(_get_alternative, _set_alternative)


class Foot_crossing(_ElementText):
    """
    Foot crossing, child of L{Note}

    DTD definition::
        <!ELEMENT foot_crossing (#PCDATA)>
        <!ATTLIST foot_crossing
            %id;
            value (change|front|behind) #IMPLIED>

    Foot crossing for the organ pedal.
    """
    _req_attrs = ['id_']
    _attrs = ['value']
    def __init__(self, id_, text, value=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['change','front','behind']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #change-front-behind

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',1:'change',
            2:'front',3:'behind'}, 0)
    value = property(_get_value, _set_value)


class Generic_text(_ElementText):
    """
    Generic text, child of L{Score_data}, L{Part}, L{Metronome}

    DTD definition::
        <!ELEMENT generic_text (#PCDATA)>
        <!ATTLIST generic_text
            %id;
            type CDATA          #IMPLIED
            value CDATA         #IMPLIED
            xml:lang CDATA      #IMPLIED
            line_of_continuation (1|2) #IMPLIED>

    Generic text is a multipurpose element can be used to encode text
    used in a score and that is not encoded as L{Dynamic}.
    C{type} is the category to which the text pertains. Known values are
    I{title,opus,author,description,expression,annotation,text}.
    New values can be set by the user.
    C{value} is the unicode text ready to be used in a translation process.
    """
    _req_attrs = ['id_']
    _attrs = ['type_','value','lang','line_of_continuation']
    def __init__(self, id_, text, type_=None, value=None, lang=None,
        line_of_continuation=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param type_: the type of this text
        @param value: unicode text
        @param lang: language as xml:lang
        @param line_of_continuation: 1 or 2
        """
        _ElementText.__init__(self, id_, text)
        self.type_ = type_
        self.value = value
        self.lang = lang
        self.line_of_continuation = line_of_continuation

    def _get_line_of_continuation(self):
        return self._line_of_continuation
    def _set_line_of_continuation(self, value):
        self._line_of_continuation = value
    line_of_continuation = property(_get_line_of_continuation,
        _set_line_of_continuation)


class Hand(_ElementText):
    """
    Hand, child of L{Part}

    DTD definition::
        <!ELEMENT hand (#PCDATA)>
        <!ATTLIST hand
            %id;
            value (left|right|left_only|organ_pedal)  #REQUIRED
            chord_dir (up|down)   #IMPLIED>

    C{chord_dir} is the chord reading direction, if missing default to I{down}
    """
    _req_attrs = ['id_','value']
    _attrs = ['chord_dir']
    def __init__(self, id_, text, value, chord_dir=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['left', 'right']
        @param chord_dir: C{string} in ['up', 'down']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #left-right
        self.chord_dir = chord_dir #up-down

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        #self._value = _Left_right(value)
        self._value = _NamedEnumerator(value, {0:'',1:'left',
            2:'right',3:'left_only',4:'organ_pedal'}, 0)
    value = property(_get_value, _set_value)

    def _get_chord_dir(self):
        return self._chord_dir
    def _set_chord_dir(self, value):
        self._chord_dir = _Up_dn(value)
    chord_dir = property(_get_chord_dir, _set_chord_dir)


class Harmonic(_ElementText):
    """
    Harmonic, child of L{Note}, L{Interval}

    DTD definition::
        <!ELEMENT harmonic (#PCDATA)>
        <!ATTLIST harmonic
            %id;
            value (natural|artificial) #REQUIRED
            doubled (true|false)    #IMPLIED>
    """
    _req_attrs = ['id_','value']
    _attrs = ['doubled']
    def __init__(self, id_, text, value, doubled=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['natural','artificial']
        @param doubled: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.doubled = doubled

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',1:'natural',
            2:'artificial'}, 0)
    value = property(_get_value, _set_value)

    def _get_doubled(self):
        return self._doubled
    def _set_doubled(self, value):
        self._doubled = _True_false(value)
    doubled = property(_get_doubled, _set_doubled)


class Inaccord(_ElementText):
    """
    Inaccord, child of L{Part}

    DTD definition::
        <!ELEMENT inaccord (#PCDATA)>
        <!ATTLIST inaccord
            %id;
            value CDATA         #REQUIRED>

    C{value} is one of I{full} for full-measure, I{part} for part-measure,
    or I{division} for measure division for part-measure inaccord.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['full', 'part', 'division']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',
            1:'full',#3254
            2:'part',#6041
            3:'division',#6111
            }, 0)
    value = property(_get_value, _set_value)


class Interval(_ElementContainer):
    """
    Interval, child of L{Note}

    DTD definition::
        <!ELEMENT interval (shift_line?,
            harmonic?,accordion_row?,accidental?,octave?,interval_type,
            (fingering|(string_fingering,harmonic?)|
            (harmonic,string_fingering)|organ_pedal)?,
            tie?,shift_line?)>
        <!ATTLIST interval
            %id;>

    Interval is the container for all the elements that precedes or follows an
    L{Interval_type}.

    @todo: add L{Stem}.
    """
    _req_attrs = ['id_']
    _elements = ['accordion_row','accidental','octave',
        'interval_type',
        'fingering','string_fingering','organ_pedal','tie']
    _elements_ls = ['shift_line','harmonic']

    def __init__(self, id_):
        """
        @param id_: id
        """
        _ElementContainer.__init__(self, id_)

    value = property(lambda self: self.get_interval_type().value)
    doubled = property(lambda self: self.get_interval_type().doubled)

    def get_accordion_row(self):
        return self._get_element('accordion_row')
    def set_accordion_row(self, item):
        self._set_element('accordion_row', item)
    #def insert_accordion_row(self, item, next_item=None):
    #   self._insert_element('accordion_row', item, next_item)
    def del_accordion_row(self):
        self._del_element('accordion_row')

    def get_accidental(self):
        return self._get_element('accidental')
    def set_accidental(self, item):
        self._set_element('accidental', item)
    #def insert_accidental(self, item, next_item=None):
    #   self._insert_element('accidental', item, next_item)
    def del_accidental(self):
        self._del_element('accidental')

    def get_octave(self):
        return self._get_element('octave')
    def set_octave(self, item):
        self._set_element('octave', item)
    #def insert_octave(self, item, next_item=None):
    #   self._insert_element('octave', item, next_item)
    def del_octave(self):
        self._del_element('octave')

    def get_interval_type(self):
        return self._get_element('interval_type')
    def set_interval_type(self, item):
        self._set_element('interval_type', item)
    #def insert_interval_type(self, item, next_item=None):
    #   self._insert_element('interval_type', item, next_item)
    def del_interval_type(self):
        self._del_element('interval_type')

    def get_fingering(self):
        return self._get_element('fingering')
    def set_fingering(self, item):
        self._set_element('fingering', item)
    #def insert_fingering(self, item, next_item=None):
    #   self._insert_element('fingering', item, next_item)
    def del_fingering(self):
        self._del_element('fingering')

    def get_string_fingering(self):
        return self._get_element('string_fingering')
    def set_string_fingering(self, item):
        self._set_element('string_fingering', item)
    #def insert_string_fingering(self, item, next_item=None):
    #   self._insert_element('string_fingering', item, next_item)
    def del_string_fingering(self):
        self._del_element('string_fingering')

    def get_organ_pedal(self):
        return self._get_element('organ_pedal')
    def set_organ_pedal(self, item):
        self._set_element('organ_pedal', item)
    #def insert_organ_pedal(self, item, next_item=None):
    #   self._insert_element('organ_pedal', item, next_item)
    def del_organ_pedal(self):
        self._del_element('organ_pedal')

    def get_tie(self):
        return self._get_element('tie')
    def set_tie(self, item):
        self._set_element('tie', item)
    #def insert_tie(self, item, next_item=None):
    #   self._insert_element('tie', item, next_item)
    def del_tie(self):
        self._del_element('tie')

    def get_shift_line(self):
        return self._get_element_ls('get_shift_line')
    def add_shift_line(self, item, index=None):
        self._add_element('shift_line', item, index)
    def insert_shift_line(self, item, next_item=None):
        self._insert_element('shift_line', item, next_item)
    def del_shift_line(self, item):
        self._del_element('shift_line', item)
    def extend_shift_line(self, items):
        self._extend_element('shift_line', items)

    def get_harmonic(self):
        return self._get_element_ls('get_harmonic')
    def add_harmonic(self, item, index=None):
        self._add_element('harmonic', item, index)
    def insert_harmonic(self, item, next_item=None):
        self._insert_element('harmonic', item, next_item)
    def del_harmonic(self, item):
        self._del_element('harmonic', item)
    def extend_harmonic(self, items):
        self._extend_element('harmonic', items)


class Interval_data(_ElementContainer):
    """
    Interval_data, child of L{Interval_ref}

    DTD definition::
        <!ELEMENT interval_data (pitch,alteration?,ties?)>

    Container for calculated data.
    """
    _elements = ['pitch','alteration','ties']
    _doc_element = False  #this element has not a doc representation

    def __init__(self):
        _ElementContainer.__init__(self)

    def __iter__(self):
        yield self.get_pitch()
        for item in self._elements[1:]:
            v = getattr(self, 'get_'+item)()
            if v is not None:
                yield v

    def get_pitch(self):
        return self._get_element('pitch')
    def set_pitch(self, item):
        self._set_element('pitch', item)
    #def insert_pitch(self, item, next_item=None):
    #   self._insert_element('pitch', item, next_item)
    def del_pitch(self):
        self._del_element('pitch')

    def _get_pitch(self):
        return self.get_pitch().value
##    def _set_pitch(self, value):
##        obj = self.get_pitch()
##        if obj:
##            obj.value = value
##        else:
##            self.set_pitch(Pitch(value=value))
##    pitch = property(_get_pitch, _set_pitch)
    pitch = property(_get_pitch)

    def get_alteration(self):
        return self._get_element('alteration')
    def set_alteration(self, item):
        self._set_element('alteration', item)
    #def insert_alteration(self, item, next_item=None):
    #   self._insert_element('alteration', item, next_item)
    def del_alteration(self):
        self._del_element('alteration')

    def _get_alteration(self):
        obj = self.get_alteration()
        return obj.value if obj else None
##    def _set_alteration(self, value):
##        obj = self.get_alteration()
##        if value is not None:
##            if obj:
##                obj.value = value
##            else:
##                self.set_alteration(Alteration(value=value))
##        elif obj:
##            self.del_alteration()
##    alteration = property(_get_alteration, _set_alteration, _del_alteration)
    alteration = property(_get_alteration, fdel=del_alteration)

##    def _get_show_alteration(self):
##        obj = self.get_alteration()
##        return (obj.show is True) if obj else False
##    def _set_show_alteration(self, value):
##        obj = self.get_alteration()
##        if obj:
##            obj.show = value
##        else:
##            raise AttributeError('no alteration: cannot set show alteration')
##    show_alteration = property(_get_show_alteration, _set_show_alteration)

    def get_ties(self):
        return self._get_element('ties')
    def set_ties(self, item):
        self._set_element('ties', item)
    #def insert_ties(self, item, next_item=None):
    #   self._insert_element('ties', item, next_item)
    def del_ties(self):
        self._del_element('ties')

    def _get_ties(self):
        s = self.get_ties()
        if s is not None: return s.get_tie_ref()
        return []
    ties = property(_get_ties, fdel=del_ties)


class Interval_ref(_ElementContainer, _ElementProxy):
    """
    Interval_ref, child of L{Intervals}

    DTD definition::
        <!ELEMENT interval_ref (interval_data)>
        <!ATTLIST interval_ref
            %id_ref;>

    Refers to the interval element written for this note or for a previous
    one in case of doubling. The L{Interval_data} contains the calculated data
    for the interval.
    """
    _req_attrs = ['id_']
    _elements = ['interval_data']
    _doc_element = False  #this element has not a doc representation

    def __init__(self, id_):
        """
        @param id_: id
        """
        _ElementContainer.__init__(self, id_=id_)
        del self.id_  #remove id_ from this class
        _ElementProxy.__init__(self, ref_id_=id_)
        #self._data = Interval_data()
        #self.set_interval_data(self._data) #force data initialization
##        self.set_interval_data(Interval_data()) #force data initialization
        self.data = None

    def __getattr__(self, name):
        try:
            return _ElementContainer.__getattr__(self, name)
        except:
            return _ElementProxy.__getattr__(self, name)

    def get_interval_data(self):
        return self._get_element('interval_data')
    def set_interval_data(self, item):
        if item is not None:
            self._set_element('interval_data', item)
        self._data = item
    #def insert_interval_data(self, item, next_item=None):
    #   self._insert_element('interval_data', item, next_item)
    def del_interval_data(self):
        self._del_element('interval_data')
    data = property(lambda self: self._data, set_interval_data)

    def get_text(self):
        """ override get_text to get text from referred """
        return self._ref.get_text()


class Interval_type(_ElementText):
    """
    Interval_type, child of L{Interval}

    DTD definition::
        <!ELEMENT interval_type (#PCDATA)>
        <!ATTLIST interval_type
            %id;
            value CDATA         #REQUIRED
            doubled (true|false)    #IMPLIED>

    C{value} ranges from 2 to 8. If the interval is written
    in doubled form the C{doubled} attribute is true.

    Real pitch of the interval depends on various parameters like chord reading
    direction, presence of an octave sing in front of the interval and by the
    Braille rule for intervals. The real pitch is encoded in L{Interval_data}.
    """
    _req_attrs = ['id_','value']
    _attrs = ['doubled']

    def __init__(self, id_, text, value, doubled=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int} from 2 to 8
        @param doubled: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #int
        self.doubled = doubled #None,True

    def _get_doubled(self):
        return self._doubled
    def _set_doubled(self, value):
        self._doubled = _True_false(value)
    doubled = property(_get_doubled, _set_doubled)


class Intervals(_ElementContainer):
    """
    Intervals, child of L{Note_data}

    DTD definition::
        <!ELEMENT intervals (interval_ref+)>

    Container for interval references.
    """
    _elements_ls = ['interval_ref']
    _doc_element = False  #this element has not a doc representation

    def get_interval_ref(self):
        return self._get_element_ls('interval_ref')
    def add_interval_ref(self, item, index=None):
        self._add_element('interval_ref', item, index)
    def insert_interval_ref(self, item, next_item=None):
        self._insert_element('interval_ref', item, next_item)
    def del_interval_ref(self, item):
        self._del_element('interval_ref', item)
    def extend_interval_ref(self, items):
        self._extend_element('interval_ref', items)


class Key_signature(_ElementText):
    """
    Key signature, child of L{Score_data}, L{Part}

    DTD definition::
        <!ELEMENT key_signature (#PCDATA)>
        <!ATTLIST key_signature
            %id;
            value CDATA         #REQUIRED
            cancel CDATA        #IMPLIED>

    Key signature can be written as child of L{Part}, acting only on this part,
    or for all the parts as child of L{Score_data}.

    C{value} is the alterations value, ranging from -7 to 7. C{cancel} is the
    number of naturals used to cancel a previous key signature,
    ranging from 0 to 7.
    """
    _req_attrs = ['id_','value']
    _attrs = ['cancel']
    def __init__(self, id_, text, value, cancel=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int} from -7 to 7
        @param cancel: C{int} from 0 to 7
        """
        _ElementText.__init__(self, id_, text)
        self.value = value  #-7...7
        self.cancel = cancel #1...7


class Line_of_continuation(_ElementText):
    """
    Line of continuation, child of L{Part}

    DTD definition::
        <!ELEMENT line_of_continuation (#PCDATA)>
        <!ATTLIST line_of_continuation
            %id;
            value (start|stop) #REQUIRED
            number  (1|2)   #IMPLIED>

    """
    _req_attrs = ['id_','value']
    _attrs = ['number']
    def __init__(self, id_, text, value, number=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['start','stop']
        @param number: C{int}, 0 or 1
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.number = number

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _Start_stop(value)
    value = property(_get_value, _set_value)


class Lyric(_ElementContainer):
    """
    Lyric, child of L{Score_data}

    DTD definition::
        <!ELEMENT lyric (lyric_prefix?,(syllable|syllable_mute|lyric_repeat|space)+)>
        <!ATTLIST lyric
            %id;
            xml:lang CDATA      #IMPLIED>

    Is the container for a lyric line written before or after the music. The
    lyric text is divided in syllables. The link between a syllable and a note
    is in the L{Note_data}/L{Lyrics} references.

    C{xml:lang} is the language used for this lyric. A lyric text written in
    more than a language can be encoded using the C{xml:lang} for each syllable,
    see L{Syllabic_text}.
    """
    _req_attrs = ['id_']
##    _attrs = ['lang','placement','position','font_data']
    _attrs = ['lang']
    _elements = ['lyric_prefix']
    _elements_ls = ['syllable', 'lyric_repeat', 'space','syllable_mute']
##    def __init__(self, id_, lang=None, placement=None, position=None, font_data=None):
    def __init__(self, id_, lang=None):
        """
        @param id_: id
        @param lang: language as xml:lang
        """
        _ElementContainer.__init__(self, id_)
        self.lang = lang
##        self.placement = placement #above-below
##        self.position = position    #int
##        self.font_data = font_data  #tuple: pointSize,style,weight,faceName

##    def _get_placement(self):
##        return self._placement
##    def _set_placement(self, value):
##        self._placement = _Above_below(value)
##    placement = property(_get_placement, _set_placement)

    def get_lyric_prefix(self):
        return self._get_element('lyric_prefix')
    def set_lyric_prefix(self, item):
        self._set_element('lyric_prefix', item)
    #def insert_lyric_prefix(self, item, next_item=None):
    #   self._insert_element('lyric_prefix', item, next_item)
    def del_lyric_prefix(self):
        self._del_element('lyric_prefix')

    def get_syllable(self):
        return self._get_element_ls('syllable')
    def add_syllable(self, item, index=None):
        self._add_element('syllable', item, index)
    def insert_syllable(self, item, next_item=None):
        self._insert_element('syllable', item, next_item)
    def del_syllable(self, item):
        self._del_element('syllable', item)
    def extend_syllable(self, items):
        self._extend_element('syllable', items)

    def get_lyric_repeat(self):
        return self._get_element_ls('lyric_repeat')
    def add_lyric_repeat(self, item, index=None):
        self._add_element('lyric_repeat', item, index)
    def insert_lyric_repeat(self, item, next_item=None):
        self._insert_element('lyric_repeat', item, next_item)
    def del_lyric_repeat(self, item):
        self._del_element('lyric_repeat', item)
    def extend_lyric_repeat(self, items):
        self._extend_element('lyric_repeat', items)

    def get_space(self):
        return self._get_element_ls('space')
    def add_space(self, item, index=None):
        self._add_element('space', item, index)
    def insert_space(self, item, next_item=None):
        self._insert_element('space', item, next_item)
    def del_space(self, item):
        self._del_element('space', item)
    def extend_space(self, items):
        self._extend_element('space', items)

    def get_syllable_mute(self):
        return self._get_element_ls('syllable_mute')
    def add_syllable_mute(self, item, index=None):
        self._add_element('syllable_mute', item, index)
    def insert_syllable_mute(self, item, next_item=None):
        self._insert_element('syllable_mute', item, next_item)
    def del_syllable_mute(self, item):
        self._del_element('syllable_mute', item)
    def extend_syllable_mute(self, items):
        self._extend_element('syllable_mute', items)


class Lyric_prefix(_ElementText):
    """
    Lyric prefix, child of L{Lyric}

    DTD definition::
        <!ELEMENT lyric_prefix (#PCDATA)>
        <!ATTLIST lyric_prefix
            %id;>

    Is the prefix for a line of lyric.
    """
    _req_attrs = ['id_']
    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
        _ElementText.__init__(self, id_, text)


class Lyric_repeat(_ElementContainer):
    """
    Lyric repeat, child of L{Lyric}

    DTD definition::
        <!ELEMENT lyric_repeat
            ((number?,lyric_repetition,(syllable|syllable_mute|space)+,lyric_repetition)|
            (lyric_repetition,(syllable|syllable_mute|space)+,lyric_repetition,number?))>
        <!ATTLIST lyric_repeat
            %id;>

    Container for repeating a lyric chunk of text. The L{Lyric_repetition}
    Braille symbol is written before and after the part of text to be repeated.
    Can be preceded or followed by a number, or can be doubled.
    """
    _req_attrs = ['id_']
    _elements = ['number']
    _elements_ls = ['lyric_repetition', 'syllable', 'syllable_mute', 'space']
    ##def __init__(self, id_):
    ##    _ElementContainer.__init__(self, id_)

    def get_number(self):
        return self._get_element('number')
    def set_number(self, item):
        self._set_element('number', item)
    #def insert_number(self, item, next_item=None):
    #   self._insert_element('number', item, next_item)
    def del_number(self):
        self._del_element('number')

    def get_lyric_repetition(self):
        return self._get_element_ls('lyric_repetition')
    def add_lyric_repetition(self, item, index=None):
        self._add_element('lyric_repetition', item, index)
    def insert_lyric_repetition(self, item, next_item=None):
        self._insert_element('lyric_repetition', item, next_item)
    def del_lyric_repetition(self, item):
        self._del_element('lyric_repetition', item)
    def extend_lyric_repetition(self, items):
        self._extend_element('lyric_repetition', items)

    def get_syllable(self):
        return self._get_element_ls('syllable')
    def add_syllable(self, item, index=None):
        self._add_element('syllable', item, index)
    def insert_syllable(self, item, next_item=None):
        self._insert_element('syllable', item, next_item)
    def del_syllable(self, item):
        self._del_element('syllable', item)
    def extend_syllable(self, items):
        self._extend_element('syllable', items)

    def get_syllable_mute(self):
        return self._get_element_ls('syllable_mute')
    def add_syllable_mute(self, item, index=None):
        self._add_element('syllable_mute', item, index)
    def insert_syllable_mute(self, item, next_item=None):
        self._insert_element('syllable_mute', item, next_item)
    def del_syllable_mute(self, item):
        self._del_element('syllable_mute', item)
    def extend_syllable_mute(self, items):
        self._extend_element('syllable_mute', items)

    def get_space(self):
        return self._get_element_ls('space')
    def add_space(self, item, index=None):
        self._add_element('space', item, index)
    def insert_space(self, item, next_item=None):
        self._insert_element('space', item, next_item)
    def del_space(self, item):
        self._del_element('space', item)
    def extend_space(self, items):
        self._extend_element('space', items)


class Lyric_repetition(_ElementText):
    """
    Lyric repetition, child of L{Lyric_repeat}

    DTD definition::
        <!ELEMENT lyric_repetition (#PCDATA)>
        <!ATTLIST lyric_repetition
            %id;
            doubled (true|false)    #IMPLIED>

    Is the Braille symbol for repeating a lyric chucnk of text. Can be doubled
    as indicated in the C{doubled} attribute.
    """
    _req_attrs = ['id_']
    _attrs = ['doubled']
    def __init__(self, id_, text, doubled=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param doubled: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.doubled = doubled #None,True

    def _get_doubled(self):
        return self._doubled
    def _set_doubled(self, value):
        self._doubled = _True_false(value)
    doubled = property(_get_doubled, _set_doubled)


class Lyrics(_ElementContainer):
    """
    Lyrics reference container, child of L{Note_data}

    DTD definition::
        <!ELEMENT lyrics (syllable_ref)+>

    Container for the syllable references, L{Syllable_ref}. Each note can have
    one or more syllables associated as in the case of various verses.
    """
    _elements_ls = ['syllable_ref']
    _doc_element = False  #this element has not a doc representation

    def get_syllable_ref(self):
        return self._get_element_ls('syllable_ref')
    def add_syllable_ref(self, item, index=None):
        self._add_element('syllable_ref', item, index)
    def insert_syllable_ref(self, item, next_item=None):
        self._insert_element('syllable_ref', item, next_item)
    def del_syllable_ref(self, item):
        self._del_element('syllable_ref', item)
    def extend_syllable_ref(self, items):
        self._extend_element('syllable_ref', items)


class Merged_text(_ElementText):
    """
    Merged text, child of L{Note}

    DTD definition::
        <!ELEMENT merged_text (#PCDATA)>
        <!ATTLIST merged_text
            %id;
            value CDATA         #REQUIRED>

    Braille symbol used for merging more syllables on a note. C{value} is the
    number of merged syllables, ranging from 2 to 4.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int} from 2 to 4
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #int


class Metronome(_ElementContainer):
    """
    Metronome, child of L{Score_data}

    DTD definition::
        <!ELEMENT metronome ((generic_text,space)?,
            metronome_note_type,(metronome_equal,(metronome_value|metronome_note_type))?)>
        <!ATTLIST metronome
            %id;>

    @todo: handle other markings as MM=120 or two notes=one note
    """
    _req_attrs = ['id_']
    _elements = ['generic_text','space','metronome_equal','metronome_value']
    _elements_ls = ['metronome_note_type']

    def get_generic_text(self):
        return self._get_element('generic_text')
    def set_generic_text(self, item):
        self._set_element('generic_text', item)
    #def insert_generic_text(self, item, next_item=None):
    #   self._insert_element('generic_text', item, next_item)
    def del_generic_text(self):
        self._del_element('generic_text')

    def get_space(self):
        return self._get_element('space')
    def set_space(self, item):
        self._set_element('space', item)
    #def insert_space(self, item, next_item=None):
    #   self._insert_element('space', item, next_item)
    def del_space(self):
        self._del_element('space')

    def get_metronome_equal(self):
        return self._get_element('metronome_equal')
    def set_metronome_equal(self, item):
        self._set_element('metronome_equal', item)
    #def insert_metronome_equal(self, item, next_item=None):
    #   self._insert_element('metronome_equal', item, next_item)
    def del_metronome_equal(self):
        self._del_element('metronome_equal')

    def get_metronome_value(self):
        return self._get_element('metronome_value')
    def set_metronome_value(self, item):
        self._set_element('metronome_value', item)
    #def insert_metronome_value(self, item, next_item=None):
    #   self._insert_element('metronome_value', item, next_item)
    def del_metronome_value(self):
        self._del_element('metronome_value')

    def get_metronome_note_type(self):
        return self._get_element_ls('metronome_note_type')
    def add_metronome_note_type(self, item, index=None):
        self._add_element('metronome_note_type', item, index)
    def insert_metronome_note_type(self, item, next_item=None):
        self._insert_element('metronome_note_type', item, next_item)
    def del_metronome_note_type(self, item):
        self._del_element('metronome_note_type', item)
    def extend_metronome_note_type(self, items):
        self._extend_element('metronome_note_type', items)


class Metronome_equal(_ElementText):
    """
    Metronome equal, child of L{Metronome}

    DTD definition::
        <!ELEMENT metronome_equal (#PCDATA)>
        <!ATTLIST metronome_equal
            %id;>

    Is the equal sign between two elements of a metronome marking.
    """
    _req_attrs = ['id_']
    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
        _ElementText.__init__(self, id_, text)


class Metronome_note_type(_ElementText):
    """
    Metronome note type, child of L{Metronome}

    DTD definition::
        <!ELEMENT metronome_note_type (#PCDATA)>
        <!ATTLIST metronome_note_type
            %id;
            value (8th_or_128th|quarter_or_64th|half_or_32nd|whole_or_16th|brevis|longa)  #REQUIRED
            dot (true|false) #IMPLIED>

    The metronome note type is similar to the L{Note_type} element. The only
    difference is that a C note is used and the C{dot} attribute.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value, dot=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['8th_or_128th','quarter_or_64th',
            'half_or_32nd','whole_or_16th','brevis','longa']
        @param dot: True/False
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.dot = dot

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {-1:'',
            0:'8th_or_128th',1:'quarter_or_64th',
            2:'half_or_32nd',3:'whole_or_16th',4:'brevis',5:'longa'}, -1)
    value = property(_get_value, _set_value)

    def _get_dot(self):
        return self._dot
    def _set_dot(self, value):
        self._dot = _True_false(value)
    dot = property(_get_dot, _set_dot)


class Metronome_value(_ElementText):
    """
    Metronome value, child of L{Metronome}

    DTD definition::
        <!ELEMENT metronome_value (#PCDATA)>
        <!ATTLIST metronome_value
            %id;
            value CDATA         #REQUIRED>

    The metronome value is the numeric value written after the equal sign. It
    can be a single number or a string. The C{value} attribute is an integer
    value or a tuple of integer, when multiple values are used.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{tuple of int}
        """
        _ElementText.__init__(self, id_, text)
        self.value = value

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _Tuple_int(value)
    value = property(_get_value, _set_value)


class Midi_instrument(_Element):
    """
    Midi instrument, child of L{Part_data}

    DTD definition::
        <!ELEMENT midi_instrument EMPTY>
        <!ATTLIST midi_instrument
            value CDATA         #REQUIRED>

    C{value} is the MIDI value, from 0 to 128.
    """
    _req_attrs = ['value']
    def __init__(self, value):
        """
        @param value: C{int} from 0 to 128
        """
        _Element.__init__(self)
        self.value = value


class Midi_metronome(_Element):
    """
    Midi metronome, child of L{Score_header}

    DTD definition::
        <!ELEMENT midi_metronome EMPTY>
        <!ATTLIST midi_metronome
            value CDATA         #REQUIRED>

    C{value} is the metronome value in quarters per minute, example "120".
    """
    _req_attrs = ['value']
    def __init__(self, value):
        """
        @param value: C{int} in quarters per minute.
        """
        _Element.__init__(self)
        self.value = value


class Multimeasure(_ElementValue):
    """
    Multimeasure, child of L{Rest_data}

    DTD definition::
        <!ELEMENT multimeasure (#PCDATA)>

    Number of measures for this rest. This value can be encoded in the
    L{Rest_type} element, for a multi measure rest written as a sequence
    of Braille signs or can be encoded in the L{Number} element preceding
    the L{Rest_type}.
    """
    pass


class Music_hyphen(_ElementText):
    """
    Music hyphen, child of L{Part}

    DTD definition::
        <!ELEMENT music_hyphen (#PCDATA)>
        <!ATTLIST music_hyphen
            %id;>
    """
    _req_attrs = ['id_']
    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
        _ElementText.__init__(self, id_, text)


class Name(_ElementText):
    """
    Name, child of L{Part_data}

    DTD definition::
        <!ELEMENT name (#PCDATA)>
        <!ATTLIST name
            %id;
            value CDATA     #IMPLIED>

    Part name as written used in the Braille score. C{value} is the unicode
    text used for converting to other format, as MusicXML.

    @todo: move lang from part_data into this element.
    """
    _req_attrs = ['id_']
    _attrs = ['value']
    def __init__(self, id_, text, value=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: unicode text
        """
        _ElementText.__init__(self, id_, text)
        self.value = value  #text in ink (unicode)


class Newline(_ElementText):
    """
    Newline, child of L{Score_data}, L{Part}

    DTD definition::
        <!ELEMENT newline (#PCDATA)>
        <!ATTLIST newline
            %id;>
    """
    _req_attrs = ['id_']
    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
        _ElementText.__init__(self, id_, text)


class Note(_ElementContainer):
    """
    Note, child of L{Part}

    DTD definition::
        <!ELEMENT note (note_data,
                foot_crossing?,
                slur?,shift_line?,(bow|stroke)?,pizzicato?,right_string_fingering?,
                tuplet*,value_prefix?,
                ornament*,nuance*,
                harmonic?,accordion_row?,accidental?,octave?,
                note_type,
                dot?,
                (fingering|(string_fingering,harmonic?)|
                (harmonic,string_fingering)|organ_pedal)?,
                ((slur,interval*,
                (tremolo|alternation)?,fermata?,(merged_text?|syllabic_slur*))|
                (interval*,
                (tremolo|alternation)?,fermata?,(merged_text?|syllabic_slur*),
                slur?)),
                tie?,shift_line?)>
        <!ATTLIST note
            %id;>

    A minimal note encoding contains L{Note_data} and L{Note_type}. The first
    is the place for all the calculated data, the latter is the written Braille
    note. Before and after L{Note_type} usually are written several other
    Braille elements. The order of signs is not always defined and can vary with
    the national conventions.
    """
    _req_attrs = ['id_']
    #_attrs = ['stemdir','stemlen','beams','cross_staff']
    #_elements = ['note_data','slur_before','tuplet','value_prefix',
    #    'accidental','octave',
    #    'note_type',
    #    'dot', 'fingering','tremolo','alternation',
    #    'slur', 'fermata',
    #    'merged_text',
    #    ]
    #_elements_ls = ['ornament','nuance','interval','tie',
    #    'syllabic_slur',]
    _elements = ['note_data','foot_crossing','shift_line','right_string_fingering',
        'value_prefix','bow','stroke','pizzicato',
        'accordion_row','accidental','octave',
        'note_type',
        'dot', 'fingering','string_fingering','organ_pedal','tremolo','alternation',
        'fermata',
        'merged_text',
        ]
    _elements_ls = ['tuplet','ornament','nuance','interval','slur','tie',
        'syllabic_slur','shift_line','harmonic']

##    def __init__(self, id_, stemdir=None, stemlen=None, beams=None, cross_staff=None):
    def __init__(self, id_):
        """ @param id_: id """
        _ElementContainer.__init__(self, id_)
##        self.stemdir = stemdir  #up-dn
##        self.stemlen = stemlen  #int
##        self.beams = beams      #tuple: left, right ints
##        self.cross_staff = cross_staff  #None,True
        #force data initialization
        ##self._data = Note_data()
        ##self.set_note_data(self._data)
##        self.set_note_data(Note_data())
        self.data = None

    def __iter__(self):
        """ iterator with note_data as first item """
        yield self.data
        for i in _ElementContainer.__iter__(self):
            if i != self.data:
                yield i

##    def _get_stemdir(self):
##        return self._stemdir
##    def _set_stemdir(self, value):
##        self._stemdir = _Up_dn(value)
##    stemdir = property(_get_stemdir, _set_stemdir)
##
##    def _get_beams(self):
##        return self._beams
##    def _set_beams(self, value):
##        self._beams = _Tuple_int(value)
##    beams = property(_get_beams, _set_beams)
##
##    def _get_cross_staff(self):
##        return self._cross_staff
##    def _set_cross_staff(self, value):
##        self._cross_staff = _True_false(value)
##    cross_staff = property(_get_cross_staff, _set_cross_staff)

    def get_note_data(self):
        return self._get_element('note_data')
    def set_note_data(self, item):
        if item is not None:
            self._set_element('note_data', item)
        self._data = item
    #def insert_note_data(self, item, next_item=None):
    #   self._insert_element('note_data', item, next_item)
    def del_note_data(self):
        self._del_element('note_data')
    data = property(lambda self: self._data, set_note_data)

    def get_foot_crossing(self):
        return self._get_element('foot_crossing')
    def set_foot_crossing(self, item):
        self._set_element('foot_crossing', item)
    #def insert_foot_crossing(self, item, next_item=None):
    #   self._insert_element('foot_crossing', item, next_item)
    def del_foot_crossing(self):
        self._del_element('foot_crossing')

    def get_tuplet(self):
        return self._get_element_ls('tuplet')
    def add_tuplet(self, item, index=None):
        self._add_element('tuplet', item, index)
    def insert_tuplet(self, item, next_item=None):
        self._insert_element('tuplet', item, next_item)
    def del_tuplet(self, item):
        self._del_element('tuplet', item)
    def extend_tuplet(self, items):
        self._extend_element('tuplet', items)

    def get_value_prefix(self):
        return self._get_element('value_prefix')
    def set_value_prefix(self, item):
        self._set_element('value_prefix', item)
    #def insert_value_prefix(self, item, next_item=None):
    #   self._insert_element('value_prefix', item, next_item)
    def del_value_prefix(self):
        self._del_element('value_prefix')

    def get_bow(self):
        return self._get_element('bow')
    def set_bow(self, item):
        self._set_element('bow', item)
    #def insert_bow(self, item, next_item=None):
    #   self._insert_element('bow', item, next_item)
    def del_bow(self):
        self._del_element('bow')

    def get_pizzicato(self):
        return self._get_element('pizzicato')
    def set_pizzicato(self, item):
        self._set_element('pizzicato', item)
    #def insert_pizzicato(self, item, next_item=None):
    #   self._insert_element('pizzicato', item, next_item)
    def del_pizzicato(self):
        self._del_element('pizzicato')

    def get_right_string_fingering(self):
        return self._get_element('right_string_fingering')
    def set_right_string_fingering(self, item):
        self._set_element('right_string_fingering', item)
    #def insert_right_string_fingering(self, item, next_item=None):
    #   self._insert_element('right_string_fingering', item, next_item)
    def del_right_string_fingering(self):
        self._del_element('right_string_fingering')

    def get_accordion_row(self):
        return self._get_element('accordion_row')
    def set_accordion_row(self, item):
        self._set_element('accordion_row', item)
    #def insert_accordion_row(self, item, next_item=None):
    #   self._insert_element('accordion_row', item, next_item)
    def del_accordion_row(self):
        self._del_element('accordion_row')

    def get_accidental(self):
        return self._get_element('accidental')
    def set_accidental(self, item):
        self._set_element('accidental', item)
    #def insert_accidental(self, item, next_item=None):
    #   self._insert_element('accidental', item, next_item)
    def del_accidental(self):
        self._del_element('accidental')

    def get_octave(self):
        return self._get_element('octave')
    def set_octave(self, item):
        self._set_element('octave', item)
    #def insert_octave(self, item, next_item=None):
    #   self._insert_element('octave', item, next_item)
    def del_octave(self):
        self._del_element('octave')

    def get_note_type(self):
        return self._get_element('note_type')
    def set_note_type(self, item):
        self._set_element('note_type', item)
    #def insert_note_type(self, item, next_item=None):
    #   self._insert_element('note_type', item, next_item)
    def del_note_type(self):
        self._del_element('note_type')

    def get_dot(self):
        return self._get_element('dot')
    def set_dot(self, item):
        self._set_element('dot', item)
    #def insert_dot(self, item, next_item=None):
    #   self._insert_element('dot', item, next_item)
    def del_dot(self):
        self._del_element('dot')

    def get_fingering(self):
        return self._get_element('fingering')
    def set_fingering(self, item):
        self._set_element('fingering', item)
    #def insert_fingering(self, item, next_item=None):
    #   self._insert_element('fingering', item, next_item)
    def del_fingering(self):
        self._del_element('fingering')

    def get_string_fingering(self):
        return self._get_element('string_fingering')
    def set_string_fingering(self, item):
        self._set_element('string_fingering', item)
    #def insert_string_fingering(self, item, next_item=None):
    #   self._insert_element('string_fingering', item, next_item)
    def del_string_fingering(self):
        self._del_element('string_fingering')

    def get_organ_pedal(self):
        return self._get_element('organ_pedal')
    def set_organ_pedal(self, item):
        self._set_element('organ_pedal', item)
    #def insert_organ_pedal(self, item, next_item=None):
    #   self._insert_element('organ_pedal', item, next_item)
    def del_organ_pedal(self):
        self._del_element('organ_pedal')

    def get_tremolo(self):
        return self._get_element('tremolo')
    def set_tremolo(self, item):
        self._set_element('tremolo', item)
    #def insert_tremolo(self, item, next_item=None):
    #   self._insert_element('tremolo', item, next_item)
    def del_tremolo(self):
        self._del_element('tremolo')

    def get_alternation(self):
        return self._get_element('alternation')
    def set_alternation(self, item):
        self._set_element('alternation', item)
    #def insert_alternation(self, item, next_item=None):
    #   self._insert_element('alternation', item, next_item)
    def del_alternation(self):
        self._del_element('alternation')

    def get_fermata(self):
        return self._get_element('fermata')
    def set_fermata(self, item):
        self._set_element('fermata', item)
    #def insert_fermata(self, item, next_item=None):
    #   self._insert_element('fermata', item, next_item)
    def del_fermata(self):
        self._del_element('fermata')

    def get_merged_text(self):
        return self._get_element('merged_text')
    def set_merged_text(self, item):
        self._set_element('merged_text', item)
    #def insert_merged_text(self, item, next_item=None):
    #   self._insert_element('merged_text', item, next_item)
    def del_merged_text(self):
        self._del_element('merged_text')

    def get_ornament(self):
        return self._get_element_ls('ornament')
    def add_ornament(self, item, index=None):
        self._add_element('ornament', item, index)
    def insert_ornament(self, item, next_item=None):
        self._insert_element('ornament', item, next_item)
    def del_ornament(self, item):
        self._del_element('ornament', item)
    def extend_ornament(self, items):
        self._extend_element('ornament', items)

    def get_nuance(self):
        return self._get_element_ls('nuance')
    def add_nuance(self, item, index=None):
        self._add_element('nuance', item, index)
    def insert_nuance(self, item, next_item=None):
        self._insert_element('nuance', item, next_item)
    def del_nuance(self, item):
        self._del_element('nuance', item)
    def extend_nuance(self, items):
        self._extend_element('nuance', items)

    def get_interval(self):
        return self._get_element_ls('interval')
    def add_interval(self, item, index=None):
        self._add_element('interval', item, index)
    def insert_interval(self, item, next_item=None):
        self._insert_element('interval', item, next_item)
    def del_interval(self, item):
        self._del_element('interval', item)
    def extend_interval(self, items):
        self._extend_element('interval', items)

    def get_slur(self):
        return self._get_element_ls('slur')
    def add_slur(self, item, index=None):
        self._add_element('slur', item, index)
    def insert_slur(self, item, next_item=None):
        self._insert_element('slur', item, next_item)
    def del_slur(self, item):
        self._del_element('slur', item)
    def extend_slur(self, items):
        self._extend_element('slur', items)

    def get_tie(self):
        return self._get_element_ls('tie')
    def add_tie(self, item, index=None):
        self._add_element('tie', item, index)
    def insert_tie(self, item, next_item=None):
        self._insert_element('tie', item, next_item)
    def del_tie(self, item):
        self._del_element('tie', item)
    def extend_tie(self, items):
        self._extend_element('tie', items)

    def get_syllabic_slur(self):
        return self._get_element_ls('syllabic_slur')
    def add_syllabic_slur(self, item, index=None):
        self._add_element('syllabic_slur', item, index)
    def insert_syllabic_slur(self, item, next_item=None):
        self._insert_element('syllabic_slur', item, next_item)
    def del_syllabic_slur(self, item):
        self._del_element('syllabic_slur', item)
    def extend_syllabic_slur(self, items):
        self._extend_element('syllabic_slur', items)

    def get_shift_line(self):
        return self._get_element_ls('shift_line')
    def add_shift_line(self, item, index=None):
        self._add_element('shift_line', item, index)
    def insert_shift_line(self, item, next_item=None):
        self._insert_element('shift_line', item, next_item)
    def del_shift_line(self, item):
        self._del_element('shift_line', item)
    def extend_shift_line(self, items):
        self._extend_element('shift_line', items)

    def get_harmonic(self):
        return self._get_element_ls('harmonic')
    def add_harmonic(self, item, index=None):
        self._add_element('harmonic', item, index)
    def insert_harmonic(self, item, next_item=None):
        self._insert_element('harmonic', item, next_item)
    def del_harmonic(self, item):
        self._del_element('harmonic', item)
    def extend_harmonic(self, items):
        self._extend_element('harmonic', items)

    #def get_slur_x(self):
    #    """ return slur and slur_before items """
    #    ret = []
    #    sl = self.get_slur()
    #    if sl is not None:
    #        ret.append(sl)
    #    sb = self.get_slur_before()
    #    if sb is not None:
    #        ret.append(sb)
    #    return ret


class Note_data(_ElementContainer):
    """
    Note data, child of L{Note}

    DTD definition::
        <!ELEMENT note_data (pitch,(duration|appoggiatura_ref),alteration?,
            rhythmic_group?,
            tuplets?,slurs?,ties?,intervals?,nuances?,tremolo_ref?,alternation_ref?,
            lyrics?)>

    Is the container for all the calculated data for this note. Children are of
    three types: simple values, as L{Pitch} or L{Duration}, single references as
    L{Appoggiatura_ref}, list of references as L{Slurs}.
    """
    _elements = ['pitch','duration','appoggiatura_ref','alteration',
        'rhythmic_group',
        'tuplets','slurs','ties','intervals','nuances','tremolo_ref',
        'alternation_ref','lyrics']
    _doc_element = False  #this element has not a doc representation
    ##def __init__(self):
    ##    _ElementContainer.__init__(self)
    ##    #self.__dict__

    def __iter__(self):
        yield self.get_pitch()
        duration = self.get_duration()
        if duration is not None:
            yield duration
        else:
            yield self.get_appoggiatura_ref()
        for item in self._elements[3:]:
            v = getattr(self, 'get_'+item)()
            if v is not None:
                yield v

    def get_pitch(self):
        return self._get_element('pitch')
    def set_pitch(self, item):
        self._set_element('pitch', item)
    #def insert_pitch(self, item, next_item=None):
    #   self._insert_element('pitch', item, next_item)
    def del_pitch(self):
        self._del_element('pitch')

    def _get_pitch(self):
        return self.get_pitch().value
##    def _set_pitch(self, value):
##        obj = self.get_pitch()
##        if obj:
##            obj.value = value
##        else:
##            self.set_pitch(Pitch(value=value))
##    pitch = property(_get_pitch, _set_pitch,
##        doc='integer value with middle C = 28')
    pitch = property(_get_pitch,
        doc='integer value with middle C = 28')

    def get_duration(self):
        return self._get_element('duration')
    def set_duration(self, item):
        self._set_element('duration', item)
    #def insert_duration(self, item, next_item=None):
    #   self._insert_element('duration', item, next_item)
    def del_duration(self):
        self._del_element('duration')

    def _get_duration(self):
        return self.get_duration().value
##    def _set_duration(self, value):
##        obj = self.get_duration()
##        if obj:
##            obj.value = value
##        else:
##            self.set_duration(Duration(value=value))
##    duration = property(_get_duration, _set_duration,
##        doc='integer value with quarter=1024')
    duration = property(_get_duration,
        del_duration,
        doc='integer value with quarter=1024')

    def get_appoggiatura_ref(self):
        return self._get_element('appoggiatura_ref')
    def set_appoggiatura_ref(self, item):
        self._set_element('appoggiatura_ref', item)
    #def insert_appoggiatura_ref(self, item, next_item=None):
    #   self._insert_element('appoggiatura_ref', item, next_item)
    def del_appoggiatura_ref(self):
        self._del_element('appoggiatura_ref')

    def _get_appoggiatura(self):
        a = self.get_appoggiatura_ref()
        if a is None or not a.isbound():
            return None
        return a.value
    appoggiatura = property(_get_appoggiatura,
        fdel=lambda self: self.del_appoggiatura_ref(),
        doc='appoggiatura reference value')

##    def _set_appoggiatura_ref(self, ornament):
##        if isinstance(ornament, Ornament) and ornament.value in ['appoggiatura','short_appoggiatura']:
##            obj = self.get_appoggiatura_ref()
##            if not obj:
##                obj = Appoggiatura_ref(ornament.id_)
##                self.set_appoggiatura_ref(obj)
##            obj.bind(ornament)
##        else:
##            raise ValueError('%s is not an (appoggiatura ) ornament instance' % str(ornament))
##    appoggiatura_ref = property(lambda self: self.get_appoggiatura_ref(),
##        _set_appoggiatura_ref,
##        lambda self: self.del_appoggiatura_ref(),
##        doc='appoggiatura reference')
    appoggiatura_ref = property(lambda self: self.get_appoggiatura_ref(),
        fdel=lambda self: self.del_appoggiatura_ref(),
        doc='appoggiatura reference')

    def get_alteration(self):
        return self._get_element('alteration')
    def set_alteration(self, item):
        self._set_element('alteration', item)
    #def insert_alteration(self, item, next_item=None):
    #   self._insert_element('alteration', item, next_item)
    def del_alteration(self):
        self._del_element('alteration')

    def _get_alteration(self):
        obj = self.get_alteration()
        return obj.value if obj else None
##    def _set_alteration(self, value):
##        obj = self.get_alteration()
##        if value != None:
##            if obj:
##                obj.value = value
##            else:
##                self.set_alteration(Alteration(value=value))
##        elif obj:
##            self.del_alteration()
##    alteration = property(_get_alteration, _set_alteration,
##        lambda self: self.del_alteration(),
##        doc='integer value from -2 = 2 flats to +2 = 2 sharps')
    alteration = property(_get_alteration,
        fdel=lambda self: self.del_alteration(),
        doc='integer value from -2 = 2 flats to +2 = 2 sharps')

##    def _get_show_alteration(self):
##        obj = self.get_alteration()
##        return (obj.show is True) if obj else False
##    def _set_show_alteration(self, value):
##        obj = self.get_alteration()
##        if obj:
##            obj.show = value
##        else:
##            raise AttributeError('no alteration: cannot set show alteration')
##    show_alteration = property(_get_show_alteration, _set_show_alteration)

    def get_rhythmic_group(self):
        return self._get_element('rhythmic_group')
    def set_rhythmic_group(self, item):
        self._set_element('rhythmic_group', item)
    #def insert_rhythmic_group(self, item, next_item=None):
    #   self._insert_element('rhythmic_group', item, next_item)
    def del_rhythmic_group(self):
        self._del_element('rhythmic_group')

    def _get_rhythmic_group(self):
        return self.get_rhythmic_group().value
##    def _set_rhythmic_group(self, value):
##        obj = self.get_rhythmic_group()
##        if obj:
##            obj.value = value
##        else:
##            self.set_rhythmic_group(Rhythmic_group(value=value))
##    rhythmic_group = property(_get_rhythmic_group, _set_rhythmic_group,
##        doc='string value in start,stop,continue')
    rhythmic_group = property(_get_rhythmic_group,
        doc='string value in start,stop,continue')

    def get_tuplets(self):
        return self._get_element('tuplets')
    def set_tuplets(self, item):
        self._set_element('tuplets', item)
    #def insert_tuplets(self, item, next_item=None):
    #   self._insert_element('tuplets', item, next_item)
    def del_tuplets(self):
        self._del_element('tuplets')

    def _get_tuplets(self):
        t = self.get_tuplets()
        if t is not None: return t.get_tuplet_ref()
        return []
    tuplets = property(_get_tuplets,
        fdel=lambda self: self.del_tuplets(),
        doc='list of tuplet references')

    def get_slurs(self):
        return self._get_element('slurs')
    def set_slurs(self, item):
        self._set_element('slurs', item)
    #def insert_slurs(self, item, next_item=None):
    #   self._insert_element('slurs', item, next_item)
    def del_slurs(self):
        self._del_element('slurs')

    def _get_slurs(self):
        s = self.get_slurs()
        if s is not None: return s.get_slur_ref()
        return []
    slurs = property(_get_slurs,
        fdel=lambda self: self.del_slurs(),
        doc='list of slur references')

    def get_ties(self):
        return self._get_element('ties')
    def set_ties(self, item):
        self._set_element('ties', item)
    #def insert_ties(self, item, next_item=None):
    #   self._insert_element('ties', item, next_item)
    def del_ties(self):
        self._del_element('ties')

    def _get_ties(self):
        s = self.get_ties()
        if s is not None: return s.get_tie_ref()
        return []
    ties = property(_get_ties,
        #fdel=lambda self: self.del_ties(),
        fdel=del_ties,
        doc='list of tie references')

    def get_intervals(self):
        return self._get_element('intervals')
    def set_intervals(self, item):
        self._set_element('intervals', item)
    #def insert_intervals(self, item, next_item=None):
    #   self._insert_element('intervals', item, next_item)
    def del_intervals(self):
        self._del_element('intervals')

    def _get_intervals(self):
        s = self.get_intervals()
        if s is not None: return s.get_interval_ref()
        return []
    intervals = property(_get_intervals,
        fdel=lambda self: self.del_intervals(),
        doc='list of interval references')

    def get_nuances(self):
        return self._get_element('nuances')
    def set_nuances(self, item):
        self._set_element('nuances', item)
    #def insert_nuances(self, item, next_item=None):
    #   self._insert_element('nuances', item, next_item)
    def del_nuances(self):
        self._del_element('nuances')

    def _get_nuances(self):
        s = self.get_nuances()
        if s is not None: return s.get_nuance_ref()
        return []
    nuances = property(_get_nuances,
        fdel=lambda self: self.del_nuances(),
        doc='list of nuance references')

    def get_tremolo_ref(self):
        return self._get_element('tremolo_ref')
    def set_tremolo_ref(self, item):
        self._set_element('tremolo_ref', item)
    #def insert_tremolo_ref(self, item, next_item=None):
    #   self._insert_element('tremolo_ref', item, next_item)
    def del_tremolo_ref(self):
        self._del_element('tremolo_ref')

    def _get_tremolo(self):
        t = self.get_tremolo_ref()
        if t is None or not t.isbound():
            return None
        return t.value
    tremolo = property(_get_tremolo,
        fdel=lambda self: self.del_tremolo_ref(),
        doc='tremolo reference value')

##    def _set_tremolo_ref(self, tremolo):
##        if isinstance(tremolo, Tremolo):
##            obj = self.get_tremolo_ref()
##            if not obj:
##                obj = Tremolo_ref(tremolo.id_)
##                self.set_tremolo_ref(obj)
##            obj.bind(tremolo)
##        else:
##            raise ValueError('%s is not a tremolo' % str(tremolo))
##    tremolo_ref = property(lambda self: self.get_tremolo_ref(),
##        _set_tremolo_ref,
##        fdel=lambda self: self.del_tremolo_ref(),
##        doc='tremolo reference')
    tremolo_ref = property(lambda self: self.get_tremolo_ref(),
        fdel=lambda self: self.del_tremolo_ref(),
        doc='tremolo reference')

    def get_alternation_ref(self):
        return self._get_element('alternation_ref')
    def set_alternation_ref(self, item):
        self._set_element('alternation_ref', item)
    #def insert_alternation_ref(self, item, next_item=None):
    #   self._insert_element('alternation_ref', item, next_item)
    def del_alternation_ref(self):
        self._del_element('alternation_ref')

    def _get_alternation(self):
        t = self.get_alternation_ref()
        if t is None or not t.isbound():
            return None
        return t.value
    alternation = property(_get_alternation,
        fdel=lambda self: self.del_alternation_ref(),
        doc='alternation reference value')
##    def _set_alternation_ref(self, alternation):
##        if isinstance(alternation, Alternation):
##            obj = self.get_alternation_ref()
##            if not obj:
##                obj = Alternation_ref(alternation.id_, type_=None)
##                self.set_alternation_ref(obj)
##            obj.bind(alternation)
##        else:
##            raise ValueError('%s is not an alternation' % str(alternation))
##    alternation_ref = property(lambda self: self.get_alternation_ref(),
##        _set_alternation_ref,
##        fdel=lambda self: self.del_alternation_ref(),
##        doc='alternation reference')
    alternation_ref = property(lambda self: self.get_alternation_ref(),
        fdel=lambda self: self.del_alternation_ref(),
        doc='alternation reference')

    def get_lyrics(self):
        return self._get_element('lyrics')
    def set_lyrics(self, item):
        self._set_element('lyrics', item)
    #def insert_lyrics(self, item, next_item=None):
    #   self._insert_element('lyrics', item, next_item)
    def del_lyrics(self):
        self._del_element('lyrics')

    def _get_lyrics(self):
        t = self.get_lyrics()
        #if t is not None: return t.get_lyric_ref()
        if t is not None: return t.get_syllable_ref()
        return []
    lyrics = property(_get_lyrics, fdel=lambda self: self.del_lyrics(),
        doc='list of lyric references')


class Note_ref(_ElementProxy):
    """
    Note reference, child of L{Stem_data}

    DTD definition::
        <!ELEMENT note_ref EMPTY>
        <!ATTLIST note_ref
            %id_ref;>

    @todo: remove this element when Stem is placed as child of L{Note} or
    L{Interval}
    """
    _req_attrs = ['id_']
    def __init__(self, id_):
        """ @param id_: reference id """
        _ElementProxy.__init__(self, ref_id_=id_)

    #def is_container(self):
    #    """ hide container """
    #    return False


class Note_type(_ElementText):
    """
    Note type, child of L{Note}

    DTD definition::
        <!ELEMENT note_type (#PCDATA)>
        <!ATTLIST note_type
            %id;
            name (A|B|C|D|E|F|G)    #REQUIRED
            value (8th_or_128th|quarter_or_64th|half_or_32nd|whole_or_16th|brevis|longa)  #REQUIRED>
    """
    _req_attrs = ['id_','name','value']
    def __init__(self, id_, text, name, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param name: C{string} in ['A', ..., 'G']
        @param value: C{string} in ['8th_or_128th','quarter_or_64th',
            'half_or_32nd','whole_or_16th','brevis','longa']
        """
        _ElementText.__init__(self, id_, text)
        self.name = name    #string A...G (1...7)
        self.value = value

    def _get_name(self):
        return self._name
    def _set_name(self, value):
        self._name = _NamedEnumerator(value, {-1:'',
            0:'C',1:'D',2:'E',3:'F',4:'G',5:'A',6:'B',}, -1)
    name = property(_get_name, _set_name)

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {-1:'',
            0:'8th_or_128th',1:'quarter_or_64th',
            2:'half_or_32nd',3:'whole_or_16th',4:'brevis',5:'longa'}, -1)
    value = property(_get_value, _set_value)


class Nuance(_ElementText):
    """
    Nuance, child of L{Note}

    DTD definition::
        <!ELEMENT nuance (#PCDATA)>
        <!ATTLIST nuance
            %id;
            value CDATA         #REQUIRED
            doubled (true|false)    #IMPLIED>

    C{value} is the name of the nuance. Know values are I{staccato,
    staccatissimo, mezzo_staccato, marcato, accento, accento_inverso,
    martellato}
    """
    _req_attrs = ['id_','value']
##    _attrs = ['doubled','placement','position']
    _attrs = ['doubled']
    def __init__(self, id_, text, value, doubled=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['staccato', 'staccatissimo', 'mezzo_staccato',
            'marcato', 'accento', 'accento_inverso', 'martellato']
        @param doubled: True or False
        """
##    def __init__(self, id_, text, value, doubled=None, placement=None, position=None):
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.doubled = doubled  #None,True
##        self.placement = placement #above-below
##        self.position = position    #int

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',
            1:'staccato',2:'staccatissimo',3:'mezzo_staccato',
            4:'marcato',5:'accento',6:'accento_inverso', 7:'martellato'}, 0)
    value = property(_get_value, _set_value)

    def _get_doubled(self):
        return self._doubled
    def _set_doubled(self, value):
        self._doubled = _True_false(value)
    doubled = property(_get_doubled, _set_doubled)

##    def _get_placement(self):
##        return self._placement
##    def _set_placement(self, value):
##        self._placement = _Above_below(value)
##    placement = property(_get_placement, _set_placement)


class Nuance_ref(_ElementProxy):
    """
    Nuance reference, child of L{Nuances}

    DTD definition::
        <!ELEMENT nuance_ref EMPTY>
        <!ATTLIST nuance_ref
            %id_ref;>


    Refers to the nuance element written for this note or for a previous
    one in case of doubling.
    """
    _req_attrs = ['id_']
    def __init__(self, id_):
        """
        @param id_: id
        """
        _ElementProxy.__init__(self, ref_id_=id_)

    #def is_container(self):
    #    """ hide container """
    #    return False


class Nuances(_ElementContainer):
    """
    Nuances, child of L{Note_data}

    DTD definition::
        <!ELEMENT nuances (nuance_ref+)>

    Container for nuance references, see L{Nuance_ref}
    """
    _elements_ls = ['nuance_ref']
    _doc_element = False  #this element has not a doc representation

    def get_nuance_ref(self):
        return self._get_element_ls('nuance_ref')
    def add_nuance_ref(self, item, index=None):
        self._add_element('nuance_ref', item, index)
    def insert_nuance_ref(self, item, next_item=None):
        self._insert_element('nuance_ref', item, next_item)
    def del_nuance_ref(self, item):
        self._del_element('nuance_ref', item)
    def extend_nuance_ref(self, items):
        self._extend_element('nuance_ref', items)


class Number(_ElementText):
    """
    Number, child of ...

    DTD definition::
        <!ELEMENT number (#PCDATA)>
        <!ATTLIST number
            %id;
            value CDATA         #REQUIRED>

    Number written as number sing followed by digits. C{value} is the number value.
    @todo: change this to include different kind of numbers.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int}
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #int


class Octave(_ElementText):
    """
    Octave, child of L{Interval}, L{Note}, L{Repeat}

    DTD definition::
        <!ELEMENT octave (#PCDATA)>
        <!ATTLIST octave
            %id;
            value CDATA         #REQUIRED
            position CDATA      #IMPLIED>

    C{value} and C{position} range from 0 to 8 where 0 is below first octave and
    8 is above seventh octave.
    C{position} is used when two octave marks are used for print "8va",
    the first used for position and the latter for the actual octave,
    see NIM 1-13.
    """
    _req_attrs = ['id_','value']
    _attrs = ['position']
    def __init__(self, id_, text, value, position=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int} from 0 to 8
        @param position: C{int} from 0 to 7
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #int 0..7
        self.position = position  #int 0..7


class Organ_pedal(_ElementText):
    """
    Organ pedal, child of L{Note}, L{Interval}

    DTD definition::
        <!ELEMENT organ_pedal (#PCDATA)>
        <!ATTLIST organ_pedal
            %id;
            value (left_toe|left_heel|right_toe|right_heel) #REQUIRED
            substitution (left_toe|left_heel|right_toe|right_heel) #IMPLIED>

    Foot sign for the organ pedal.
    """
    _req_attrs = ['id_','value']
    _attrs = ['substitution']
    def __init__(self, id_, text, value, substitution=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['left_toe','left_heel','right_toe','right_heel']
        @param substitution: C{string} in ['left_toe','left_heel','right_toe','right_heel']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.substitution = substitution

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',
            1:'left_toe',2:'left_heel',
            3:'right_toe',4:'right_heel'}, 0)
    value = property(_get_value, _set_value)

    def _get_substitution(self):
        return self._substitution
    def _set_substitution(self, value):
        self._substitution = _NamedEnumerator(value, {0:'',1:'left_toe',2:'left_heel',
            3:'right_toe',4:'right_heel'}, 0)
    substitution = property(_get_substitution, _set_substitution)


class Ornament(_ElementContainer):
    """
    Ornament, child of L{Note}

    DTD definition::
        <!ELEMENT ornament (accidental*,ornament_type)>
        <!ATTLIST ornament
            %id;>
    """
    _req_attrs = ['id_']
    _elements = ['ornament_type']
    _elements_ls = ['accidental']
    #def __init__(self, id_):
    #    _ElementContainer.__init__(self, id_)

    value = property(lambda self: self.get_ornament_type().value)
    doubled = property(lambda self: self.get_ornament_type().doubled)

    def get_ornament_type(self):
        return self._get_element('ornament_type')
    def set_ornament_type(self, item):
        self._set_element('ornament_type', item)
    #def insert_ornament_type(self, item, next_item=None):
    #   self._insert_element('ornament_type', item, next_item)
    def del_ornament_type(self):
        self._del_element('ornament_type')

    def get_accidental(self):
        return self._get_element_ls('accidental')
    def add_accidental(self, item, index=None):
        self._add_element('accidental', item, index)
    def insert_accidental(self, item, next_item=None):
        self._insert_element('accidental', item, next_item)
    def del_accidental(self, item):
        self._del_element('accidental', item)
    def extend_accidental(self, items):
        self._extend_element('accidental', items)


class Ornament_type(_ElementText):
    """
    Ornament_type, child of L{Ornament}

    DTD definition::
        <!ELEMENT ornament_type (#PCDATA)>
        <!ATTLIST ornament_type
            %id;
            value CDATA         #REQUIRED
            doubled (true|false)    #IMPLIED>

    Known values for C{value} are I{trill, appoggiatura, short_appoggiatura,
    turn, turn_above, inverted_turn, inverted_turn_above,
    short_trill, extended_short_trill,
    mordent, extended_mordent,
    arpeggio_up, extended_arpeggio_up,
    arpeggio_down ,extended_arpeggio_down}
    """
    _req_attrs = ['id_','value']
    _attrs = ['doubled']
    def __init__(self, id_, text, value, doubled=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['trill', 'appoggiatura', 'short_appoggiatura',
            'turn', 'turn_above', 'inverted_turn', 'inverted_turn_above',
            'short_trill', 'extended_short_trill',
            'mordent', 'extended_mordent',
            'arpeggio_up', 'extended_arpeggio_up',
            'arpeggio_down', 'extended_arpeggio_down']
        @param doubled: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.doubled = doubled  #None,True

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',
            1:'trill',2:'appoggiatura',3:'short_appoggiatura',
            4:'turn',5:'turn_above',6:'inverted_turn',7:'inverted_turn_above',
            8:'short_trill',9:'extended_short_trill',
            10:'mordent',11:'extended_mordent',
            12:'arpeggio_up',13:'extended_arpeggio_up',
            14:'arpeggio_down',15:'extended_arpeggio_down'}, 0)
    value = property(_get_value, _set_value)

    def _get_doubled(self):
        return self._doubled
    def _set_doubled(self, value):
        self._doubled = _True_false(value)
    doubled = property(_get_doubled, _set_doubled)


class Part(_ElementContainer):
    """
    Part, child of L{Score_data}

    DTD definition::
        <!ELEMENT part (part_name?, (space|newline|key_signature|time_signature|clef|
                    note|stem|rest|inaccord|barline|repeat|
                    music_hyphen|dynamic|ending|separator|hand|segno|coda|generic_text|
                    pedal|chord_prefix|chord|line_of_continuation|
                    string|barre|string_position|rasgueado|accordion_register|breath|
                    right_string_fingering|fermata|
                    unknown)+)>
        <!ATTLIST part
            %id;>

    Part is a container for musical elements, starts with
    a L{Part_name} followed by music data. Each part is identified by an id and
    linked by this value to the corresponding L{Part_data} entry in the
    L{Part_list}. The sequence of parts follows the Braille document layout.
    For example in a section by section format score for piano, we have two
    L{Part_data} entries in the L{Part_list}. In the L{Score_data} section
    we have a sequence of parts, each one starting with the L{Part_name},
    that is left hand or right hand. A part ends with new line or when a new
    part starts.

    One exception to the above is a single part that has no name. This is a
    special case used for simple examples or short pieces where there's no
    part indication. In this case the L{Part_name} is missing.

    Elements that are outside the part elements apply to the document.
    For example a key signature written before the parts apply to all the parts,
    while a key signature written after the L{Part_name}, that is inside the
    part, apply only to this part.

    @todo: elements inside a part are not grouped by measure. Do we need to
    change this?
    """
    _req_attrs = ['id_']
    _elements = ['part_name']
    _elements_ls= ['space', 'clef', 'key_signature', 'time_signature',
            'note', 'stem', 'rest', 'inaccord', 'barline', 'newline', 'repeat',
            'music_hyphen','dynamic','ending', 'separator',
            'hand','segno','coda','generic_text','pedal',
            'chord_prefix','chord','line_of_continuation',
            'string','barre','string_position','rasgueado','accordion_register',
            'breath','right_string_fingering','fermata',
            'unknown',]
    #def __init__(self, id_):
    #    _ElementContainer.__init__(self, id_)

    def iter_x(self):
        """ iterator over data expanding repetition """
        it = [iter(self._ElementContainer__items)]
        while it:
            try:
                obj = it[-1].next()
                if isinstance(obj, Repeat):
                    it.append(iter(obj.data.repeats))
                else:
                    yield obj
            except StopIteration:
                it.pop()

    def get_part_name(self):
        return self._get_element('part_name')
    def set_part_name(self, item):
        self._set_element('part_name', item, index=0)
    #def insert_part_name(self, item, next_item=None):
    #   self._insert_element('part_name', item, next_item)
    def del_part_name(self):
        self._del_element('part_name')

    def get_space(self):
        return self._get_element_ls('space')
    def add_space(self, item, index=None):
        self._add_element('space', item, index)
    def insert_space(self, item, next_item=None):
        self._insert_element('space', item, next_item)
    def del_space(self, item):
        self._del_element('space', item)
    def extend_space(self, items):
        self._extend_element('space', items)

    def get_clef(self):
        return self._get_element_ls('clef')
    def add_clef(self, item, index=None):
        self._add_element('clef', item, index)
    def insert_clef(self, item, next_item=None):
        self._insert_element('clef', item, next_item)
    def del_clef(self, item):
        self._del_element('clef', item)
    def extend_clef(self, items):
        self._extend_element('clef', items)

    def get_key_signature(self):
        return self._get_element_ls('key_signature')
    def add_key_signature(self, item, index=None):
        self._add_element('key_signature', item, index)
    def insert_key_signature(self, item, next_item=None):
        self._insert_element('key_signature', item, next_item)
    def del_key_signature(self, item):
        self._del_element('key_signature', item)
    def extend_key_signature(self, items):
        self._extend_element('key_signature', items)

    def get_time_signature(self):
        return self._get_element_ls('time_signature')
    def add_time_signature(self, item, index=None):
        self._add_element('time_signature', item, index)
    def insert_time_signature(self, item, next_item=None):
        self._insert_element('time_signature', item, next_item)
    def del_time_signature(self, item):
        self._del_element('time_signature', item)
    def extend_time_signature(self, items):
        self._extend_element('time_signature', items)

    def get_note(self):
        return self._get_element_ls('note')
    def add_note(self, item, index=None):
        self._add_element('note', item, index)
    def insert_note(self, item, next_item=None):
        self._insert_element('note', item, next_item)
    def del_note(self, item):
        self._del_element('note', item)
    def extend_note(self, items):
        self._extend_element('note', items)

    def get_stem(self):
        return self._get_element_ls('stem')
    def add_stem(self, item, index=None):
        self._add_element('stem', item, index)
    def insert_stem(self, item, next_item=None):
        self._insert_element('stem', item, next_item)
    def del_stem(self, item):
        self._del_element('stem', item)
    def extend_stem(self, items):
        self._extend_element('stem', items)

    def get_rest(self):
        return self._get_element_ls('rest')
    def add_rest(self, item, index=None):
        self._add_element('rest', item, index)
    def insert_rest(self, item, next_item=None):
        self._insert_element('rest', item, next_item)
    def del_rest(self, item):
        self._del_element('rest', item)
    def extend_rest(self, items):
        self._extend_element('rest', items)

    def get_inaccord(self):
        return self._get_element_ls('inaccord')
    def add_inaccord(self, item, index=None):
        self._add_element('inaccord', item, index)
    def insert_inaccord(self, item, next_item=None):
        self._insert_element('inaccord', item, next_item)
    def del_inaccord(self, item):
        self._del_element('inaccord', item)
    def extend_inaccord(self, items):
        self._extend_element('inaccord', items)

    def get_barline(self):
        return self._get_element_ls('barline')
    def add_barline(self, item, index=None):
        self._add_element('barline', item, index)
    def insert_barline(self, item, next_item=None):
        self._insert_element('barline', item, next_item)
    def del_barline(self, item):
        self._del_element('barline', item)
    def extend_barline(self, items):
        self._extend_element('barline', items)

    def get_newline(self):
        return self._get_element_ls('newline')
    def add_newline(self, item, index=None):
        self._add_element('newline', item, index)
    def insert_newline(self, item, next_item=None):
        self._insert_element('newline', item, next_item)
    def del_newline(self, item):
        self._del_element('newline', item)
    def extend_newline(self, items):
        self._extend_element('newline', items)

    def get_repeat(self):
        return self._get_element_ls('repeat')
    def add_repeat(self, item, index=None):
        self._add_element('repeat', item, index)
    def insert_repeat(self, item, next_item=None):
        self._insert_element('repeat', item, next_item)
    def del_repeat(self, item):
        self._del_element('repeat', item)
    def extend_repeat(self, items):
        self._extend_element('repeat', items)

    def get_music_hyphen(self):
        return self._get_element_ls('music_hyphen')
    def add_music_hyphen(self, item, index=None):
        self._add_element('music_hyphen', item, index)
    def insert_music_hyphen(self, item, next_item=None):
        self._insert_element('music_hyphen', item, next_item)
    def del_music_hyphen(self, item):
        self._del_element('music_hyphen', item)
    def extend_music_hyphen(self, items):
        self._extend_element('music_hyphen', items)

    def get_dynamic(self):
        return self._get_element_ls('dynamic')
    def add_dynamic(self, item, index=None):
        self._add_element('dynamic', item, index)
    def insert_dynamic(self, item, next_item=None):
        self._insert_element('dynamic', item, next_item)
    def del_dynamic(self, item):
        self._del_element('dynamic', item)
    def extend_dynamic(self, items):
        self._extend_element('dynamic', items)

    def get_ending(self):
        return self._get_element_ls('ending')
    def add_ending(self, item, index=None):
        self._add_element('ending', item, index)
    def insert_ending(self, item, next_item=None):
        self._insert_element('ending', item, next_item)
    def del_ending(self, item):
        self._del_element('ending', item)
    def extend_ending(self, items):
        self._extend_element('ending', items)

    def get_separator(self):
        return self._get_element_ls('separator')
    def add_separator(self, item, index=None):
        self._add_element('separator', item, index)
    def insert_separator(self, item, next_item=None):
        self._insert_element('separator', item, next_item)
    def del_separator(self, item):
        self._del_element('separator', item)
    def extend_separator(self, items):
        self._extend_element('separator', items)

    def get_hand(self):
        return self._get_element_ls('hand')
    def add_hand(self, item, index=None):
        self._add_element('hand', item, index)
    def insert_hand(self, item, next_item=None):
        self._insert_element('hand', item, next_item)
    def del_hand(self, item):
        self._del_element('hand', item)
    def extend_hand(self, items):
        self._extend_element('hand', items)

    def get_segno(self):
        return self._get_element_ls('segno')
    def add_segno(self, item, index=None):
        self._add_element('segno', item, index)
    def insert_segno(self, item, next_item=None):
        self._insert_element('segno', item, next_item)
    def del_segno(self, item):
        self._del_element('segno', item)
    def extend_segno(self, items):
        self._extend_element('segno', items)

    def get_coda(self):
        return self._get_element_ls('coda')
    def add_coda(self, item, index=None):
        self._add_element('coda', item, index)
    def insert_coda(self, item, next_item=None):
        self._insert_element('coda', item, next_item)
    def del_coda(self, item):
        self._del_element('coda', item)
    def extend_coda(self, items):
        self._extend_element('coda', items)

    def get_generic_text(self):
        return self._get_element_ls('generic_text')
    def add_generic_text(self, item, index=None):
        self._add_element('generic_text', item, index)
    def insert_generic_text(self, item, next_item=None):
        self._insert_element('generic_text', item, next_item)
    def del_generic_text(self, item):
        self._del_element('generic_text', item)
    def extend_generic_text(self, items):
        self._extend_element('generic_text', items)

    def get_pedal(self):
        return self._get_element_ls('pedal')
    def add_pedal(self, item, index=None):
        self._add_element('pedal', item, index)
    def insert_pedal(self, item, next_item=None):
        self._insert_element('pedal', item, next_item)
    def del_pedal(self, item):
        self._del_element('pedal', item)
    def extend_pedal(self, items):
        self._extend_element('pedal', items)

    def get_chord_prefix(self):
        return self._get_element_ls('chord_prefix')
    def add_chord_prefix(self, item, index=None):
        self._add_element('chord_prefix', item, index)
    def insert_chord_prefix(self, item, next_item=None):
        self._insert_element('chord_prefix', item, next_item)
    def del_chord_prefix(self, item):
        self._del_element('chord_prefix', item)
    def extend_chord_prefix(self, items):
        self._extend_element('chord_prefix', items)

    def get_chord(self):
        return self._get_element_ls('chord')
    def add_chord(self, item, index=None):
        self._add_element('chord', item, index)
    def insert_chord(self, item, next_item=None):
        self._insert_element('chord', item, next_item)
    def del_chord(self, item):
        self._del_element('chord', item)
    def extend_chord(self, items):
        self._extend_element('chord', items)

    def get_line_of_continuation(self):
        return self._get_element_ls('line_of_continuation')
    def add_line_of_continuation(self, item, index=None):
        self._add_element('line_of_continuation', item, index)
    def insert_line_of_continuation(self, item, next_item=None):
        self._insert_element('line_of_continuation', item, next_item)
    def del_line_of_continuation(self, item):
        self._del_element('line_of_continuation', item)
    def extend_line_of_continuation(self, items):
        self._extend_element('line_of_continuation', items)

    def get_string(self):
        return self._get_element_ls('string')
    def add_string(self, item, index=None):
        self._add_element('string', item, index)
    def insert_string(self, item, next_item=None):
        self._insert_element('string', item, next_item)
    def del_string(self, item):
        self._del_element('string', item)
    def extend_string(self, items):
        self._extend_element('string', items)

    def get_string_position(self):
        return self._get_element_ls('string_position')
    def add_string_position(self, item, index=None):
        self._add_element('string_position', item, index)
    def insert_string_position(self, item, next_item=None):
        self._insert_element('string_position', item, next_item)
    def del_string_position(self, item):
        self._del_element('string_position', item)
    def extend_string_position(self, items):
        self._extend_element('string_position', items)

    def get_barre(self):
        return self._get_element_ls('barre')
    def add_barre(self, item, index=None):
        self._add_element('barre', item, index)
    def insert_barre(self, item, next_item=None):
        self._insert_element('barre', item, next_item)
    def del_barre(self, item):
        self._del_element('barre', item)
    def extend_barre(self, items):
        self._extend_element('barre', items)

    def get_rasgueado(self):
        return self._get_element_ls('rasgueado')
    def add_rasgueado(self, item, index=None):
        self._add_element('rasgueado', item, index)
    def insert_rasgueado(self, item, next_item=None):
        self._insert_element('rasgueado', item, next_item)
    def del_rasgueado(self, item):
        self._del_element('rasgueado', item)
    def extend_rasgueado(self, items):
        self._extend_element('rasgueado', items)

    def get_accordion_register(self):
        return self._get_element_ls('accordion_register')
    def add_accordion_register(self, item, index=None):
        self._add_element('accordion_register', item, index)
    def insert_accordion_register(self, item, next_item=None):
        self._insert_element('accordion_register', item, next_item)
    def del_accordion_register(self, item):
        self._del_element('accordion_register', item)
    def extend_accordion_register(self, items):
        self._extend_element('accordion_register', items)

    def get_breath(self):
        return self._get_element_ls('breath')
    def add_breath(self, item, index=None):
        self._add_element('breath', item, index)
    def insert_breath(self, item, next_item=None):
        self._insert_element('breath', item, next_item)
    def del_breath(self, item):
        self._del_element('breath', item)
    def extend_breath(self, items):
        self._extend_element('breath', items)

    def get_right_string_fingering(self):
        return self._get_element_ls('right_string_fingering')
    def add_right_string_fingering(self, item, index=None):
        self._add_element('right_string_fingering', item, index)
    def insert_right_string_fingering(self, item, next_item=None):
        self._insert_element('right_string_fingering', item, next_item)
    def del_right_string_fingering(self, item):
        self._del_element('right_string_fingering', item)
    def extend_right_string_fingering(self, items):
        self._extend_element('right_string_fingering', items)

    def get_fermata(self):
        return self._get_element_ls('fermata')
    def add_fermata(self, item, index=None):
        self._add_element('fermata', item, index)
    def insert_fermata(self, item, next_item=None):
        self._insert_element('fermata', item, next_item)
    def del_fermata(self, item):
        self._del_element('fermata', item)
    def extend_fermata(self, items):
        self._extend_element('fermata', items)

    def get_unknown(self):
        return self._get_element_ls('unknown')
    def add_unknown(self, item, index=None):
        self._add_element('unknown', item, index)
    def insert_unknown(self, item, next_item=None):
        self._insert_element('unknown', item, next_item)
    def del_unknown(self, item):
        self._del_element('unknown', item)
    def extend_unknown(self, items):
        self._extend_element('unknown', items)


class Part_data(_ElementContainer):
    """
    Part data, child of L{Part_list}

    DTD definition::
        <!ELEMENT part_data (name, abbr_name?, clef?, midi_instrument?, family?)>
        <!ATTLIST part_data
            %id;
            chord_dir (up|down)   #IMPLIED
            xml:lang CDATA      #IMPLIED
            transpose CDATA     #IMPLIED>

    Part data is a container for part definition entries. The C{chord_dir}
    attribute is down by default. The C{xml:lang} attribute can be set and
    applies to the L{Name} and L{Abbr_name} elements. The C{transpose} attribute
    if the value of the transpose in semitones.

    Children elements of part data are used to fully specify the part. In
    particular the L{Clef} element is used as a default clef for translating
    the BMML document to another format, where the clef for a part is not
    explicity written (as usual in Braille music). The L{Family} element
    is used for defining the category of the part. This is useful for example
    when there are elements that change their meaning or simply their speech
    output aaccording to the category: for example the L{Fingering} element
    has different names and values whether the part is a keyboard part or a
    guitar part.
    """
    _req_attrs = ['id_']
    _attrs = ['chord_dir', 'lang', 'transpose']
    _elements = ['name', 'abbr_name', 'clef', 'midi_instrument', 'family']
    _doc_element = False  #this element has not a doc representation

    def __init__(self, id_, chord_dir=None, lang=None, transpose=None):
        """
        @param id_: id
        @param chord_dir: C{string} in ['up', 'down']
        @param lang: language as xml:lang
        @param transpose: C{int} value for the transposition in semitones
        """
        _ElementContainer.__init__(self, id_)
        self.chord_dir = chord_dir          # Up_dn
        self.lang = lang                    # 'it', 'es'...
        self.transpose = transpose          # chromatic transpose

    def __iter__(self):
        for item in self._elements:
            v = getattr(self, 'get_'+item)()
            if v is not None:
                yield v

    def _get_chord_dir(self):
        return self._chord_dir
    def _set_chord_dir(self, value):
        self._chord_dir = _Up_dn(value)
    chord_dir = property(_get_chord_dir, _set_chord_dir)

    def get_name(self):
        return self._get_element('name')
    def set_name(self, item):
        self._set_element('name', item)
    #def insert_name(self, item, next_item=None):
    #   self._insert_element('name', item, next_item)
    def del_name(self):
        self._del_element('name')

    def get_abbr_name(self):
        return self._get_element('abbr_name')
    def set_abbr_name(self, item):
        self._set_element('abbr_name', item)
    #def insert_abbr_name(self, item, next_item=None):
    #   self._insert_element('abbr_name', item, next_item)
    def del_abbr_name(self):
        self._del_element('abbr_name')

    def get_clef(self):
        return self._get_element('clef')
    def set_clef(self, item):
        self._set_element('clef', item)
    #def insert_clef(self, item, next_item=None):
    #   self._insert_element('clef', item, next_item)
    def del_clef(self):
        self._del_element('clef')

    def get_midi_instrument(self):
        return self._get_element('midi_instrument')
    def set_midi_instrument(self, item):
        self._set_element('midi_instrument', item)
    #def insert_midi_instrument(self, item, next_item=None):
    #   self._insert_element('midi_instrument', item, next_item)
    def del_midi_instrument(self):
        self._del_element('midi_instrument')

    def get_family(self):
        return self._get_element('family')
    def set_family(self, item):
        self._set_element('family', item)
    #def insert_family(self, item, next_item=None):
    #   self._insert_element('family', item, next_item)
    def del_family(self):
        self._del_element('family')


class Part_list(_ElementContainer):
    """
    Part list, child of L{Score_header}

    DTD definition::
        <!ELEMENT part_list (part_data+)>

    Defines the list of part used in the document. Each entry in the part list
    must match one or more L{Part} entries in L{Score_data}.
    """
    _elements_ls = ['part_data']
    _doc_element = False  #this element has not a doc representation

    def get_part_data(self):
        return self._get_element_ls('part_data')
    def add_part_data(self, item, index=None):
        self._add_element('part_data', item, index)
    def insert_part_data(self, item, next_item=None):
        self._insert_element('part_data', item, next_item)
    def del_part_data(self, item):
        self._del_element('part_data', item)
    def extend_part_data(self, items):
        self._extend_element('part_data', items)


class Part_name(_ElementText):
    """
    Part name, child of L{Part}

    DTD definition::
        <!ELEMENT part_name (#PCDATA)>
        <!ATTLIST part_name
            %id;>

    Defines the Braille text used to start a L{Part}. Usually the text is equal
    to the L{Name} or L{Abbr_name} defined in L{Part_data}.
    """
    _req_attrs = ['id_']
    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
        _ElementText.__init__(self, id_, text)


class Pedal(_ElementText):
    """
    Pedal, child of L{Part}

    DTD definition::
        <!ELEMENT pedal (#PCDATA)>
        <!ATTLIST pedal
            %id;
            value CDATA         #REQUIRED>

    Is the piano pedal as defined in NIM 15-15 and followings.
    Known values for C{value} are I{down, up, up_down, half, up_immediately, down_up}.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['down', 'up', 'up_down',
            'half', 'up_immediately', 'down_up']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',
            1:'down',2:'up',3:'up_down',
            4:'half',5:'up_immediately',6:'down_up',}, 0)
    value = property(_get_value, _set_value)


class Pitch(_ElementValue):
    """
    Pitch, child of L{Interval_data}, L{Note_data}

    DTD definition::
        <!ELEMENT pitch (#PCDATA)>

    Is the real pitch of the note. The value is an C{int} with 28 equals to the
    middle C or C between the staves. Add 7 to go up one octave and subtract 7
    to go down one octave. Alteration values are encoded in the L{Alteration}
    element.
    """
    pass


class Pizzicato(_ElementText):
    """
    Pizzicato, child of L{Note}

    DTD definition::
        <!ELEMENT pizzicato (#PCDATA)>
        <!ATTLIST pizzicato
            %id;
            value (left|right) #REQUIRED
            doubled (true|false)    #IMPLIED>
    """
    _req_attrs = ['id_','value']
    _attrs = ['doubled']
    def __init__(self, id_, text, value, doubled=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['left','right']
        @param doubled: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.doubled = doubled

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _Left_right(value)
    value = property(_get_value, _set_value)

    def _get_doubled(self):
        return self._doubled
    def _set_doubled(self, value):
        self._doubled = _True_false(value)
    doubled = property(_get_doubled, _set_doubled)


class Rasgueado(_ElementText):
    """
    Rasgueado, child of L{Part}

    DTD definition::
        <!ELEMENT rasgueado (#PCDATA)>
        <!ATTLIST rasgueado
            %id;
            value (up|down) #REQUIRED>
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['up','down']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _Up_dn(value)
    value = property(_get_value, _set_value)


class Repeat(_ElementContainer):
    """
    Repeat, child of L{Part}

    DTD definition::
        <!ELEMENT repeat (repeat_data,
                    slur?,octave?,
                    repetition,
                    number?,slur?,tie?)>
        <!ATTLIST repeat
            %id;>

    Is the container for the C{Repeat} element.
    """
    _req_attrs = ['id_']
    #_elements = ['repeat_data','slur_before', 'octave', 'repetition', 'number', 'slur', 'tie']
    _elements = ['repeat_data','octave', 'repetition', 'number','tie']
    _elements_ls = ['slur']

    def __init__(self, id_):
        """
        @param id_: id
        """
        _ElementContainer.__init__(self, id_)
        #self._data = Repeat_data()
        #self.set_repeat_data(self._data)
##        self.set_repeat_data(Repeat_data())
        self.data = None

    def __iter__(self):
        """ iterator with note_data as first item """
        yield self.data
        for i in _ElementContainer.__iter__(self):
            if i != self.data:
                yield i

    #def get_slur_x(self):
    #    """ return slur and slur_before items """
    #    ret = []
    #    sl = self.get_slur()
    #    if sl is not None:
    #        ret.append(sl)
    #    sb = self.get_slur_before()
    #    if sb is not None:
    #        ret.append(sb)
    #    return ret
    def get_repeat_data(self):
        return self._get_element('repeat_data')
    def set_repeat_data(self, item):
        if item is not None:
            self._set_element('repeat_data', item)
        self._data = item
    #def insert_repeat_data(self, item, next_item=None):
    #   self._insert_element('repeat_data', item, next_item)
    def del_repeat_data(self):
        self._del_element('repeat_data')
    data = property(lambda self: self._data, set_repeat_data)

    def get_octave(self):
        return self._get_element('octave')
    def set_octave(self, item):
        self._set_element('octave', item)
    #def insert_octave(self, item, next_item=None):
    #   self._insert_element('octave', item, next_item)
    def del_octave(self):
        self._del_element('octave')

    def get_repetition(self):
        return self._get_element('repetition')
    def set_repetition(self, item):
        self._set_element('repetition', item)
    #def insert_repetition(self, item, next_item=None):
    #   self._insert_element('repetition', item, next_item)
    def del_repetition(self):
        self._del_element('repetition')

    def get_number(self):
        return self._get_element('number')
    def set_number(self, item):
        self._set_element('number', item)
    #def insert_number(self, item, next_item=None):
    #   self._insert_element('number', item, next_item)
    def del_number(self):
        self._del_element('number')

    def get_tie(self):
        return self._get_element('tie')
    def set_tie(self, item):
        self._set_element('tie', item)
    #def insert_tie(self, item, next_item=None):
    #   self._insert_element('tie', item, next_item)
    def del_tie(self):
        self._del_element('tie')

    def get_slur(self):
        return self._get_element_ls('slur')
    def add_slur(self, item, index=None):
        self._add_element('slur', item, index)
    def insert_slur(self, item, next_item=None):
        self._insert_element('slur', item, next_item)
    def del_slur(self, item):
        self._del_element('slur', item)
    def extend_slur(self, items):
        self._extend_element('slur', items)


class Repeat_data(_ElementContainer):
    """
    Repeat data, child of L{Repeat}

    DTD definition::
        <!ELEMENT repeat_data (repeats?)>

    Is the container for the C{Repeats} element.
    """
    _elements = ['repeats']
    _doc_element = False  #this element has not a doc representation
    #def __init__(self):
    #    _ElementContainer.__init__(self)

    def get_repeats(self):
        return self._get_element('repeats')
    def set_repeats(self, item):
        self._set_element('repeats', item)
    #def insert_repeats(self, item, next_item=None):
    #   self._insert_element('repeats', item, next_item)
    def del_repeats(self):
        self._del_element('repeats')

    def _get_repeats(self):
        s = self.get_repeats()
        if s is not None: return s.get_repeat_ref()
        return []
    repeats = property(_get_repeats,
        fdel=lambda self: self.del_repeats(),
        doc='list of repeat references')


class Repeat_ref(_ElementContainer, _ElementProxy):
    """
    Repeat reference, child of L{Repeats}

    DTD definition::
        <!ELEMENT repeat_ref ((note_data|rest_data|stem_data)?)>
        <!ATTLIST repeat_ref
            %id_ref;>

    A repeat reference is a link to a musical element that is repeated. The
    L{Note_data} or L{Rest_data} element can have the same values of the
    referred element but can also be different. For example in the case of a
    repetition with an octave sign in front, the pitch values are different.

    @todo: remove stem_data when the stem will be placed as child of note.
    """
    _req_attrs = ['id_']
    _elements = ['note_data','rest_data','stem_data']
    _doc_element = False  #this element has not a doc representation

    def __init__(self, id_, data=None):
        """
        @param id_: id
        @param data: the data value, instance of C{Note_data} or C{Rest_data}
        """
        _ElementContainer.__init__(self, id_)
        del self.id_  #remove id_ from this class
        _ElementProxy.__init__(self, ref_id_=id_)
##        if data is not None:
##            #self._data = data
##            if isinstance(data, Note_data):
##                self.set_note_data(data)
##            elif isinstance(data, Rest_data):
##                self.set_rest_data(data)
##            elif isinstance(data, Stem_data):
##                self.set_stem_data(data)
##            else:
##                self._data = None
        self.data = data

##    def __getattr__(self, name):
##        if name == 'id_':
##            print '__getattr__', self, self.get_ref().id_, _ElementProxy.__getattr__(self, name)
##            return _ElementProxy.__getattr__(self, name)
##        return super(Repeat_ref, self).__getattr__(name)
##
    def get_note_data(self):
        return self._get_element('note_data')
    def set_note_data(self, item):
        self._set_element('note_data', item)
        self._data = item
    #def insert_note_data(self, item, next_item=None):
    #   self._insert_element('note_data', item, next_item)
    def del_note_data(self):
        self._del_element('note_data')

    def get_rest_data(self):
        return self._get_element('rest_data')
    def set_rest_data(self, item):
        self._set_element('rest_data', item)
        self._data = item
    #def insert_rest_data(self, item, next_item=None):
    #   self._insert_element('rest_data', item, next_item)
    def del_rest_data(self):
        self._del_element('rest_data')

    def get_stem_data(self):
        return self._get_element('stem_data')
    def set_stem_data(self, item):
        self._set_element('stem_data', item)
        self._data = item
    #def insert_stem_data(self, item, next_item=None):
    #   self._insert_element('stem_data', item, next_item)
    def del_stem_data(self):
        self._del_element('stem_data')

    def _set_data(self, item):
        if isinstance(item, Note_data):
            self.set_note_data(item)
        elif isinstance(item, Rest_data):
            self.set_rest_data(item)
        elif isinstance(item, Stem_data):
            self.set_stem_data(item)
        else:
            self._data = None
    data = property(lambda self: self._data, _set_data)


class Repeats(_ElementContainer):
    """
    Repeats, child of L{Repeat_data}

    DTD definition::
        <!ELEMENT repeats (repeat_ref+)>

    Is the container for repeat references L{Repeat_ref}.
    """
    _elements_ls = ['repeat_ref']
    _doc_element = False  #this element has not a doc representation

    def get_repeat_ref(self):
        return self._get_element_ls('repeat_ref')
    def add_repeat_ref(self, item, index=None):
        self._add_element('repeat_ref', item, index)
    def insert_repeat_ref(self, item, next_item=None):
        self._insert_element('repeat_ref', item, next_item)
    def del_repeat_ref(self, item):
        self._del_element('repeat_ref', item)
    def extend_repeat_ref(self, items):
        self._extend_element('repeat_ref', items)


class Repetition(_ElementText):
    """
    Repetition, child of L{Repeat}

    DTD definition::
        <!ELEMENT repetition (#PCDATA)>
        <!ATTLIST repetition
            %id;
            value CDATA         #REQUIRED
            separation CDATA    #IMPLIED>

    Is the Braille repetition element. The C{value} attribute is the number
    of repetition sign written, default is 1. The C{separation} sign can be
    placed in front of a repetition sign to indicate that the repetition is
    different from the previous one as in NIM 9-19.
    """
    _req_attrs = ['id_','value']
    _attrs = ['separation']
    def __init__(self, id_, text, value, separation=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int}, number of repetitions
        @param separation: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #int
        self.separation = separation

    def _get_separation(self):
        return self._separation
    def _set_separation(self, value):
        self._separation = _True_false(value)
    separation = property(_get_separation, _set_separation)


class Rest(_ElementContainer):
    """
    Rest, child of L{Part}

    DTD definition::
        <!ELEMENT rest (rest_data,
                slur?,tuplet*,editorial_mark?,number?,value_prefix?,
                rest_type,
                dot?,slur?,fermata?)>
        <!ATTLIST rest
            %id;>

    A minimal rest encoding contains L{Rest_data} and L{Rest_type}. The first
    is the place for all the calculated data, the latter is the written Braille
    rest. Before and after L{Rest_type} usually are written several other
    Braille elements. The order of signs is not always defined and can vary with
    the national conventions.
    """
    _req_attrs = ['id_']
##    _attrs = ['position','cross_staff']
    #_elements = ['rest_data','slur_before','tuplet','editorial_mark','value_prefix',
    #    'number',
    #    'rest_type',
    #    'dot','slur','fermata',]
    _elements = ['rest_data','editorial_mark','value_prefix','number',
        'rest_type',
        'dot','fermata',]
    _elements_ls = ['tuplet','slur']

    def __init__(self, id_):
        """ @param id_: id """
##    def __init__(self, id_, position=None, cross_staff=None):
        _ElementContainer.__init__(self, id_)
##        self.position = position    #int
##        self.cross_staff = cross_staff  #None,True
        #self._data = Rest_data()
        #self.set_rest_data(self._data)
##        self.set_rest_data(Rest_data())
        self.data = None

    def __iter__(self):
        """ iterator with rest_data as first item """
        yield self.data
        for i in _ElementContainer.__iter__(self):
            if i != self.data:
                yield i

##    def _get_cross_staff(self):
##        return self._cross_staff
##    def _set_cross_staff(self, value):
##        self._cross_staff = _True_false(value)
##    cross_staff = property(_get_cross_staff, _set_cross_staff)

    def get_rest_data(self):
        return self._get_element('rest_data')
    def set_rest_data(self, item):
        if item is not None:
            self._set_element('rest_data', item)
        self._data = item
    #def insert_rest_data(self, item, next_item=None):
    #   self._insert_element('rest_data', item, next_item)
    def del_rest_data(self):
        self._del_element('rest_data')
    data = property(lambda self: self._data, set_rest_data)

    def get_tuplet(self):
        return self._get_element_ls('tuplet')
    def add_tuplet(self, item, index=None):
        self._add_element('tuplet', item, index)
    def insert_tuplet(self, item, next_item=None):
        self._insert_element('tuplet', item, next_item)
    def del_tuplet(self, item):
        self._del_element('tuplet', item)
    def extend_tuplet(self, items):
        self._extend_element('tuplet', items)


    def get_editorial_mark(self):
        return self._get_element('editorial_mark')
    def set_editorial_mark(self, item):
        self._set_element('editorial_mark', item)
    #def insert_editorial_mark(self, item, next_item=None):
    #   self._insert_element('editorial_mark', item, next_item)
    def del_editorial_mark(self):
        self._del_element('editorial_mark')

    def get_value_prefix(self):
        return self._get_element('value_prefix')
    def set_value_prefix(self, item):
        self._set_element('value_prefix', item)
    #def insert_value_prefix(self, item, next_item=None):
    #   self._insert_element('value_prefix', item, next_item)
    def del_value_prefix(self):
        self._del_element('value_prefix')

    def get_number(self):
        return self._get_element('number')
    def set_number(self, item):
        self._set_element('number', item)
    #def insert_number(self, item, next_item=None):
    #   self._insert_element('number', item, next_item)
    def del_number(self):
        self._del_element('number')

    def get_rest_type(self):
        return self._get_element('rest_type')
    def set_rest_type(self, item):
        self._set_element('rest_type', item)
    #def insert_rest_type(self, item, next_item=None):
    #   self._insert_element('rest_type', item, next_item)
    def del_rest_type(self):
        self._del_element('rest_type')

    def get_dot(self):
        return self._get_element('dot')
    def set_dot(self, item):
        self._set_element('dot', item)
    #def insert_dot(self, item, next_item=None):
    #   self._insert_element('dot', item, next_item)
    def del_dot(self):
        self._del_element('dot')

    def get_fermata(self):
        return self._get_element('fermata')
    def set_fermata(self, item):
        self._set_element('fermata', item)
    #def insert_fermata(self, item, next_item=None):
    #   self._insert_element('fermata', item, next_item)
    def del_fermata(self):
        self._del_element('fermata')

    def get_slur(self):
        return self._get_element_ls('slur')
    def add_slur(self, item, index=None):
        self._add_element('slur', item, index)
    def insert_slur(self, item, next_item=None):
        self._insert_element('slur', item, next_item)
    def del_slur(self, item):
        self._del_element('slur', item)
    def extend_slur(self, items):
        self._extend_element('slur', items)
    #def get_slur_x(self):
    #    """ return slur and slur_before items """
    #    ret = []
    #    sl = self.get_slur()
    #    if sl is not None:
    #        ret.append(sl)
    #    sb = self.get_slur_before()
    #    if sb is not None:
    #        ret.append(sb)
    #    return ret


class Rest_data(_ElementContainer):
    """
    Rest data, child of L{Rest}

    DTD definition::
        <!ELEMENT rest_data (duration,multimeasure?,
            rhythmic_group?,tuplets?,slurs?)>

    Is the container for all the calculated data for this rest. Children are of
    two types: simple values, as L{Duration}, list of references as L{Slurs}.
    """
    _elements = ['duration','multimeasure','rhythmic_group','tuplets','slurs']
    _doc_element = False  #this element has not a doc representation
    #def __init__(self):
    #    _ElementContainer.__init__(self)

    def __iter__(self):
        yield self.get_duration()
        for item in self._elements[1:]:
            v = getattr(self, 'get_'+item)()
            if v is not None:
                yield v

    def get_duration(self):
        return self._get_element('duration')
    def set_duration(self, item):
        self._set_element('duration', item)
    #def insert_duration(self, item, next_item=None):
    #   self._insert_element('duration', item, next_item)
    def del_duration(self):
        self._del_element('duration')

    def _get_duration(self):
        return self.get_duration().value
##    def _set_duration(self, value):
##        obj = self.get_duration()
##        if obj:
##            obj.value = value
##        else:
##            self.set_duration(Duration(value=value))
##    duration = property(_get_duration, _set_duration,
##        doc='integer value with quarter=1024')
    duration = property(_get_duration,
        doc='integer value with quarter=1024')

    def get_multimeasure(self):
        return self._get_element('multimeasure')
    def set_multimeasure(self, item):
        self._set_element('multimeasure', item)
    #def insert_multimeasure(self, item, next_item=None):
    #   self._insert_element('multimeasure', item, next_item)
    def del_multimeasure(self):
        self._del_element('multimeasure')

    def _get_multimeasure(self):
        m = self.get_multimeasure()
        if m:
            return m.value
        return 0
##    def _set_multimeasure(self, value):
##        obj = self.get_multimeasure()
##        if obj:
##            if value:
##                obj.value = value
##            else:
##                self.del_multimeasure()
##        elif value:
##            self.set_multimeasure(Multimeasure(value=value))
##    multimeasure = property(_get_multimeasure, _set_multimeasure,
##        doc='integer value with number of measure')
    multimeasure = property(_get_multimeasure,
        fdel=lambda self: self.del_multimeasure(),
        doc='integer value with number of measure')

    def get_rhythmic_group(self):
        return self._get_element('rhythmic_group')
    def set_rhythmic_group(self, item):
        self._set_element('rhythmic_group', item)
    #def insert_rhythmic_group(self, item, next_item=None):
    #   self._insert_element('rhythmic_group', item, next_item)
    def del_rhythmic_group(self):
        self._del_element('rhythmic_group')

    def _get_rhythmic_group(self):
        return self.get_rhythmic_group().value
##    def _set_rhythmic_group(self, value):
##        obj = self.get_duration()
##        if obj:
##            obj.value = value
##        else:
##            self.set_rhythmic_group(Rhythmic_group(value=value))
##    rhythmic_group = property(_get_rhythmic_group, _set_rhythmic_group,
##        doc='string value in start,stop,continue')
    rhythmic_group = property(_get_rhythmic_group,
        doc='string value in start,stop,continue')

    def get_tuplets(self):
        return self._get_element('tuplets')
    def set_tuplets(self, item):
        self._set_element('tuplets', item)
    #def insert_tuplets(self, item, next_item=None):
    #   self._insert_element('tuplets', item, next_item)
    def del_tuplets(self):
        self._del_element('tuplets')

    def _get_tuplets(self):
        t = self.get_tuplets()
        if t is not None: return t.get_tuplet_ref()
        return []
    tuplets = property(_get_tuplets,
        fdel=lambda self: self.del_tuplets(),
        doc='list of tuplet references')

    def get_slurs(self):
        return self._get_element('slurs')
    def set_slurs(self, item):
        self._set_element('slurs', item)
    #def insert_slurs(self, item, next_item=None):
    #   self._insert_element('slurs', item, next_item)
    def del_slurs(self):
        self._del_element('slurs')

    def _get_slurs(self):
        s = self.get_slurs()
        if s is not None: return s.get_slur_ref()
        return []
    slurs = property(_get_slurs,
        fdel=lambda self: self.del_slurs(),
        doc='list of slur references')


class Rest_type(_ElementText):
    """
    Rest type, child of L{Rest}

    DTD definition::
        <!ELEMENT rest_type (#PCDATA)>
        <!ATTLIST rest_type
            %id;
            value (8th_or_128th|quarter_or_64th|half_or_32nd|whole_or_16th|brevis|longa)  #REQUIRED
            multimeasure CDATA     #IMPLIED>

    The C{multimeasure} attribute is the number of measures for a multimeasure
    rest. For example a rest written as three consecutive Braille sign for
    three whole rests, has a multimeasure value equals to 3.
    """
    _req_attrs = ['id_','value']
    _attrs = ['multimeasure']
    def __init__(self, id_ , text, value, multimeasure=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['8th_or_128th','quarter_or_64th',
            'half_or_32nd','whole_or_16th','brevis','longa']
        @param multimeasure: C{int}, number of measures for a multimeasure rest
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.multimeasure = multimeasure #int

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {-1:'',
            0:'8th_or_128th',1:'quarter_or_64th',
            2:'half_or_32nd',3:'whole_or_16th',4:'brevis',5:'longa'}, -1)
    value = property(_get_value, _set_value)


class Rhythmic_group(_ElementValue):
    """
    Rhythmic group, child of L{Note_data}, L{Rest_data}

    DTD definition::
        <!ELEMENT rhythmic_group (#PCDATA)>

    Identifies a rhythmic group as written according to NIM.
    The value is a C{string}, one of I{start,stop,continue}.
    """

class Right_string_fingering(_ElementText):
    """
    Fingering for string for right hand, child of L{Note}, L{Part}

    DTD definition::
        <!ELEMENT right_string_fingering (#PCDATA)>
        <!ATTLIST right_string_fingering
            %id;
            value CDATA     #REQUIRED>

    C{value} from 0 to 5, with 0 used for thumb and 5 for missing fingering.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: tuple of ints
        """
        _ElementText.__init__(self, id_, text)
        self.value = value  #list of int

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _Tuple_int(value)
    value = property(_get_value, _set_value)


class Score(_ElementContainer):
    """
    Score, root of the document

    DTD definition::
        <!ELEMENT score (score_header, score_data)>
        <!ATTLIST score
            version CDATA #REQUIRED>
    """
    _req_attrs = ['version']
    _elements = ['score_header','score_data']

    def __init__(self, version=version):
        """
        @param version: the version of BMML
        """
        _ElementContainer.__init__(self)
        self.version = version

    def __iter__(self):
        yield self.get_score_header()
        yield self.get_score_data()
        raise StopIteration

    def get_score_header(self):
        return self._get_element('score_header')
    def set_score_header(self, item):
        self._set_element('score_header', item, index=0)
    #def insert_score_header(self, item, next_item=None):
    #   self._insert_element('score_header', item, next_item)
    def del_score_header(self):
        self._del_element('score_header')

    def get_score_data(self):
        return self._get_element('score_data')
    def set_score_data(self, item):
        self._set_element('score_data', item, index=1)
    #def insert_score_data(self, item, next_item=None):
    #   self._insert_element('score_data', item, next_item)
    def del_score_data(self):
        self._del_element('score_data')


class Score_data(_ElementContainer):
    """
    Score_data, child of L{Score}

    DTD definition::
        <!ELEMENT score_data (space|newline|key_signature|time_signature|
            lyric|part|unknown|metronome|generic_text)+>

    Is the container for the Braille document text elements.
    """
    _elements_ls = ['space','newline','key_signature','time_signature',
        'part','unknown','lyric','chord','metronome','generic_text']

    def iter_part_ids(self):
        """ iterator over the part ids. Return the part id """
        ids = []
        for part in self:
            if isinstance(part, Part) and part.id_ not in ids:
                ids.append(part.id_)
                yield part.id_

    def iter_part(self, id_):
        """ iterator over a part elements """
        #for part in self:
        #    if isinstance(part, Part) and part.id_ == id_:
        #        for element in part:
        #            yield element
        for part in (item for item in self if isinstance(item, Part) and item.id_ == id_):
            for element in part:
                yield element

    def iter_part_x(self, id_):
        """ iterator over a part elements (expanded version) """
        #for part in self:
        #    if isinstance(part, Part) and part.id_ == id_:
        #        for element in part.iter_x():
        #            yield element
        for part in (item for item in self if isinstance(item, Part) and item.id_ == id_):
            for element in part.iter_x():
                yield element

    def get_space(self):
        return self._get_element_ls('space')
    def add_space(self, item, index=None):
        self._add_element('space', item, index)
    def insert_space(self, item, next_item=None):
        self._insert_element('space', item, next_item)
    def del_space(self, item):
        self._del_element('space', item)
    def extend_space(self, items):
        self._extend_element('space', items)

    def get_newline(self):
        return self._get_element_ls('newline')
    def add_newline(self, item, index=None):
        self._add_element('newline', item, index)
    def insert_newline(self, item, next_item=None):
        self._insert_element('newline', item, next_item)
    def del_newline(self, item):
        self._del_element('newline', item)
    def extend_newline(self, items):
        self._extend_element('newline', items)

    def get_key_signature(self):
        return self._get_element_ls('key_signature')
    def add_key_signature(self, item, index=None):
        self._add_element('key_signature', item, index)
    def insert_key_signature(self, item, next_item=None):
        self._insert_element('key_signature', item, next_item)
    def del_key_signature(self, item):
        self._del_element('key_signature', item)
    def extend_key_signature(self, items):
        self._extend_element('key_signature', items)

    def get_time_signature(self):
        return self._get_element_ls('time_signature')
    def add_time_signature(self, item, index=None):
        self._add_element('time_signature', item, index)
    def insert_time_signature(self, item, next_item=None):
        self._insert_element('time_signature', item, next_item)
    def del_time_signature(self, item):
        self._del_element('time_signature', item)
    def extend_time_signature(self, items):
        self._extend_element('time_signature', items)

    def get_part(self):
        return self._get_element_ls('part')
    def add_part(self, item, index=None):
        self._add_element('part', item, index)
    def insert_part(self, item, next_item=None):
        self._insert_element('part', item, next_item)
    def del_part(self, item):
        self._del_element('part', item)
    def extend_part(self, items):
        self._extend_element('part', items)

    def get_unknown(self):
        return self._get_element_ls('unknown')
    def add_unknown(self, item, index=None):
        self._add_element('unknown', item, index)
    def insert_unknown(self, item, next_item=None):
        self._insert_element('unknown', item, next_item)
    def del_unknown(self, item):
        self._del_element('unknown', item)
    def extend_unknown(self, items):
        self._extend_element('unknown', items)

    def get_lyric(self):
        return self._get_element_ls('lyric')
    def add_lyric(self, item, index=None):
        self._add_element('lyric', item, index)
    def insert_lyric(self, item, next_item=None):
        self._insert_element('lyric', item, next_item)
    def del_lyric(self, item):
        self._del_element('lyric', item)
    def extend_lyric(self, items):
        self._extend_element('lyric', items)

    def get_chord(self):
        return self._get_element_ls('chord')
    def add_chord(self, item, index=None):
        self._add_element('chord', item, index)
    def insert_chord(self, item, next_item=None):
        self._insert_element('chord', item, next_item)
    def del_chord(self, item):
        self._del_element('chord', item)
    def extend_chord(self, items):
        self._extend_element('chord', items)

    def get_metronome(self):
        return self._get_element_ls('metronome')
    def add_metronome(self, item, index=None):
        self._add_element('metronome', item, index)
    def insert_metronome(self, item, next_item=None):
        self._insert_element('metronome', item, next_item)
    def del_metronome(self, item):
        self._del_element('metronome', item)
    def extend_metronome(self, items):
        self._extend_element('metronome', items)

    def get_generic_text(self):
        return self._get_element_ls('generic_text')
    def add_generic_text(self, item, index=None):
        self._add_element('generic_text', item, index)
    def insert_generic_text(self, item, next_item=None):
        self._insert_element('generic_text', item, next_item)
    def del_generic_text(self, item):
        self._del_element('generic_text', item)
    def extend_generic_text(self, items):
        self._extend_element('generic_text', items)


class Score_header(_ElementContainer):
    """
    Score_header, child of L{Score}

    DTD definition::
        <!ELEMENT score_header (meta_data?, part_list, midi_metronome?)>

    Is the header of the document, with all the definitions used to process
    the document.
    """
    _doc_element = False
    _elements = ['part_list','midi_metronome']

    def __iter__(self):
        yield self.get_part_list()
        for item in self._elements[1:]:
            v = getattr(self, 'get_'+item)()
            if v is not None:
                yield v

    def get_text(self):
        return ''  #no text returned

    def get_textlen(self):
        return 0  #no text returned

    def iter_part_data(self):
        """ iterator over part data """
        plist = self.get_part_list()
        return iter(plist.get_part_data())

    def get_part_list(self):
        return self._get_element('part_list')
    def set_part_list(self, item):
        self._set_element('part_list', item)
    #def insert_part_list(self, item, next_item=None):
    #   self._insert_element('part_list', item, next_item)
    def del_part_list(self):
        self._del_element('part_list')

    def get_midi_metronome(self):
        return self._get_element('midi_metronome')
    def set_midi_metronome(self, item):
        self._set_element('midi_metronome', item)
    #def insert_midi_metronome(self, item, next_item=None):
    #   self._insert_element('midi_metronome', item, next_item)
    def del_midi_metronome(self):
        self._del_element('midi_metronome')


class Segno(_ElementText):
    """
    Segno, child of L{Part}

    DTD definition::
        <!ELEMENT segno (#PCDATA)>
        <!ATTLIST segno
            %id;>
    """
    _req_attrs = ['id_']
##    _attrs = ['position']
    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
##    def __init__(self, id_, text, position=None):
        _ElementText.__init__(self, id_, text)
##        self.position = position    #int


class Separator(_ElementText):
    """
    Separator, child of L{Part}

    DTD definition::
        <!ELEMENT separator (#PCDATA)>
        <!ATTLIST separator
            %id;>

    Is a generic separator written in Braille as dot 3, used to separate for
    example a L{Part_name} from the following element.
    """
    _req_attrs = ['id_']
    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
        _ElementText.__init__(self, id_, text)


class Shift_line(_ElementText):
    """
    Shift line for string instruments, child of L{Part}

    DTD definition::
        <!ELEMENT shift_line (#PCDATA)>
        <!ATTLIST shift_line
            %id;
            value (glissando|start|stop)         #REQUIRED>
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['glissando','start','stop']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = self._value = _NamedEnumerator(value, {0:'',1:'glissando',
            2:'start',3:'stop'}, 0)
    value = property(_get_value, _set_value)


class Slur(_ElementText):
    """
    Slur, child of L{Note}, L{Repeat}, L{Rest}, L{Stem}

    DTD definition::
        <!ELEMENT slur (#PCDATA)>
        <!ATTLIST slur
            %id;
            value CDATA         #REQUIRED>

    Known values for C{value} are I{short, long,
    phrasing_end, short_end_begin, long_end_begin,
    phrasing_begin, phrasing_end_begin}
    """
    _req_attrs = ['id_','value']
##    _attrs = ['placement', 'line_style']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['short','long',
            'phrasing_end','short_end_begin','long_end_begin',
            'phrasing_begin','phrasing_end_begin']
        """
##    def __init__(self, id_, text, value, placement=None, line_style=None):
        _ElementText.__init__(self, id_, text)
        self.value = value
##        self.placement = placement #above-below
##        self.line_style = line_style    #solid-dashed

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',1:'short',2:'long',
            #5:'phrasing_end',6:'short_end_begin',7:'long_end_begin'}, 0)
            5:'phrasing_end',6:'short_end_begin',7:'long_end_begin',
            4:'phrasing_begin',8:'phrasing_end_begin'}, 0)
    value = property(_get_value, _set_value)

##    def _get_placement(self):
##        return self._placement
##    def _set_placement(self, value):
##        self._placement = _Above_below(value)
##    placement = property(_get_placement, _set_placement)
##
##    def _get_line_style(self):
##        return self._line_style
##    def _set_line_style(self, value):
##        #self._line_style = _Line_style(value)
##        self._line_style = _NamedEnumerator(value, {0:'',
##            1:'solid',2:'dashed'}, 0)
##    line_style = property(_get_line_style, _set_line_style)


class Slur_ref(_ElementProxy):
    """
    Slur reference, child of L{Slurs}

    DTD definition::
        <!ELEMENT slur_ref EMPTY>
        <!ATTLIST slur_ref
            %id_ref;
            type    (start|stop|continue)   #REQUIRED
            start_ref  CDATA    #REQUIRED>

    Is the reference to a L{Slur}. C{type} attribute can be start, stop or
    continue. The continue value is optional since usually only start and stop
    of a slur are cleraly determined.
    For example a short slur written in Braille as dots 1,4 is encoded
    after the first note, and a slur reference
    with C{type} equals to start is used. For the following note a slur
    reference with C{type} equals to stop is used. The C{id} and C{start_ref}
    attributes have the same values, the C{id} of the L{Slur} element.

    The C{start_ref} attribute is different from the C{id} attribute when for
    example a long slur is used. The note with the long slur, written in Braille
    as dots 1,4 and 1,4, has a slur reference to its slur element.
    A following note with a short slur is then used to close the slur. In this
    case a slur reference with the C{id} of the closing short slur is encode.
    This slur reference has a C{start_ref} value equals to the C{id} of the
    opening long slur. Last, the following note has a slur reference with C{id}
    equals to the C{id} of the closing short slur and C{start_ref} equals to the
    C{id} of the opening long slur.
    """
    _req_attrs = ['id_','type_','start_ref']
    def __init__(self, id_, type_, start_ref):
        """
        @param id_: id
        @param type_: C{string} in ['start','stop','continue']
        @param start_ref: reference to the starting slur.
        """
        _ElementProxy.__init__(self, ref_id_=id_)
        self.type_ = type_
        self.start_ref = start_ref

    def _get_type_(self):
        return self._type_
    def _set_type_(self, value):
        self._type_ = _Start_stop_continue(value)
    type_ = property(_get_type_, _set_type_)

    #def is_container(self):
    #    """ hide container """
    #    return False


class Slurs(_ElementContainer):
    """
    Slurs, child of L{Note_data}, L{Rest_data}

    DTD definition::
        <!ELEMENT slurs (slur_ref+)>

    Is the container for the L{Slur_ref} elements.
    """
    _elements_ls = ['slur_ref']
    _doc_element = False  #this element has not a doc representation

    def get_slur_ref(self):
        return self._get_element_ls('slur_ref')
    def add_slur_ref(self, item, index=None):
        self._add_element('slur_ref', item, index)
    def insert_slur_ref(self, item, next_item=None):
        self._insert_element('slur_ref', item, next_item)
    def del_slur_ref(self, item):
        self._del_element('slur_ref', item)
    def extend_slur_ref(self, items):
        self._extend_element('slur_ref', items)


class Space(_ElementText):
    """
    Space, child of L{Score_data}, L{Part}, L{Metronome}

    DTD definition::
        <!ELEMENT space (#PCDATA)>
        <!ATTLIST space
            %id;>
    """
    _req_attrs = ['id_']
    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
        _ElementText.__init__(self, id_, text)


class Stem(_ElementContainer):
    """
    Stem, child of L{Part}

    DTD definition::
        <!ELEMENT stem (stem_data,
            slur?,stem_type,dot?,slur?,tie?)>
        <!ATTLIST stem
            %id;>

    @todo: move stem inside note and interval. At the moment it is not possible
    to write a note with a stem followed by an interval.
    """
    _req_attrs = ['id_']
##    _attrs = ['stemdir','stemlen','beams']
    #_elements = ['stem_data','slur_before','stem_type','dot','slur','tie']
    _elements = ['stem_data','stem_type','dot','tie']
    _elements_ls = ['slur',]
    def __init__(self, id_):
        """ @param id_: id """
##    def __init__(self, id_, stemdir=None, stemlen=None, beams=None):
        _ElementContainer.__init__(self, id_)
##        self.stemdir = stemdir  #up-dn
##        self.stemlen = stemlen  #int
##        self.beams = beams      #tuple: left, right ints
        #self._data = Stem_data()
        #self.set_stem_data(self._data)
##        self.set_stem_data(Stem_data())
        self.data = None

##    def _get_stemdir(self):
##        return self._stemdir
##    def _set_stemdir(self, value):
##        self._stemdir = _Up_dn(value)
##    stemdir = property(_get_stemdir, _set_stemdir)
##
##    def _get_beams(self):
##        return self._beams
##    def _set_beams(self, value):
##        self._beams = _Tuple_int(value)
##    beams = property(_get_beams, _set_beams)

    def __iter__(self):
        """ iterator with note_data as first item """
        yield self.data
        for i in _ElementContainer.__iter__(self):
            if i != self.data:
                yield i

    def get_stem_data(self):
        return self._get_element('stem_data')
    def set_stem_data(self, item):
        if item is not None:
            self._set_element('stem_data', item)
        self._data = item
    #def insert_stem_data(self, item, next_item=None):
    #   self._insert_element('stem_data', item, next_item)
    def del_stem_data(self):
        self._del_element('stem_data')
    data = property(lambda self: self._data, set_stem_data)

    def get_stem_type(self):
        return self._get_element('stem_type')
    def set_stem_type(self, item):
        self._set_element('stem_type', item)
    #def insert_stem_type(self, item, next_item=None):
    #   self._insert_element('stem_type', item, next_item)
    def del_stem_type(self):
        self._del_element('stem_type')

    def get_dot(self):
        return self._get_element('dot')
    def set_dot(self, item):
        self._set_element('dot', item)
    #def insert_dot(self, item, next_item=None):
    #   self._insert_element('dot', item, next_item)
    def del_dot(self):
        self._del_element('dot')

    def get_tie(self):
        return self._get_element('tie')
    def set_tie(self, item):
        self._set_element('tie', item)
    #def insert_tie(self, item, next_item=None):
    #   self._insert_element('tie', item, next_item)
    def del_tie(self):
        self._del_element('tie')

    def get_slur(self):
        return self._get_element_ls('slur')
    def add_slur(self, item, index=None):
        self._add_element('slur', item, index)
    def insert_slur(self, item, next_item=None):
        self._insert_element('slur', item, next_item)
    def del_slur(self, item):
        self._del_element('slur', item)
    def extend_slur(self, items):
        self._extend_element('slur', items)


class Stem_data(_ElementContainer):
    """
    Stem data, child of L{Stem}

    DTD definition::
        <!ELEMENT stem_data (duration,note_ref)>

    Is the container for all the calculated data for this stem.

    @todo: with stem child of note the note_ref element is no more needed.
    """
    _elements = ['duration','note_ref']
    _doc_element = False  #this element has not a doc representation
    #def __init__(self):
    #    _ElementContainer.__init__(self)

    def __iter__(self):
        yield self.get_duration()
        for item in self._elements[1:]:
            v = getattr(self, 'get_'+item)()
            if v is not None:
                yield v

    def get_duration(self):
        return self._get_element('duration')
    def set_duration(self, item):
        self._set_element('duration', item)
    #def insert_duration(self, item, next_item=None):
    #   self._insert_element('duration', item, next_item)
    def del_duration(self):
        self._del_element('duration')

    def _get_duration(self):
        return self.get_duration().value
##    def _set_duration(self, value):
##        obj = self.get_duration()
##        if obj:
##            obj.value = value
##        else:
##            self.set_duration(Duration(value=value))
##    duration = property(_get_duration, _set_duration,
##        doc='integer value with quarter=1024')
    duration = property(_get_duration,
        doc='integer value with quarter=1024')

    def get_note_ref(self):
        return self._get_element('note_ref')
    def set_note_ref(self, item):
        self._set_element('note_ref', item)
    #def insert_note_ref(self, item, next_item=None):
    #   self._insert_element('note_ref', item, next_item)
    def del_note_ref(self):
        self._del_element('note_ref')
    note_ref = property(lambda self: self.get_note_ref(),
        fdel=lambda self: self.del_note_ref(),
        doc='note reference')

    def _get_pitch(self):
        if self.note_ref.isbound():
            return self.note_ref.data.pitch
        return None
    pitch = property(_get_pitch,
        doc='integer value with middle C = 28 (from note_ref)')

    def _get_alteration(self):
        if self.note_ref.isbound():
            return self.note_ref.data.alteration
        return None
    alteration = property(_get_alteration,
        doc='integer value from -2 = 2 flats to +2 = 2 sharps (from note_ref)')

##    def _get_show_alteration(self):
##        if self.note_ref.isbound():
##            return self.note_ref.data.show_alteration
##        return None
##    show_alteration = property(_get_show_alteration,
##        doc='True, False (from note_ref)')

##    def _set_note_ref(self, note):
##        print 'set_note_ref', note
##        if isinstance(note, Note):
##            obj = self.get_note_ref()
##            if not obj:
##                print 'new'
##                obj = Note_ref(note.id_)
##                self.set_note_ref(obj)
##            print 'bind'
##            obj.bind(note)
##        else:
##            raise ValueError('%s is not a note' % str(note))
##    note_ref = property(lambda self: self.get_note_ref(),
##        _set_note_ref,
##        fdel=lambda self: self.del_note_ref(),
##        doc='note reference')


class Stem_type(_ElementText):
    """
    Stem type, child of L{Stem}

    DTD definition::
        <!ELEMENT stem_type (#PCDATA)>
        <!ATTLIST stem_type
            %id;
            value CDATA         #REQUIRED>

    C{value} is the integer duration of the stem, with quarter equals to 1024

    @todo: change value from int to something more readable ?
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int}, duration of the stem
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #int 128...4096


class String(_ElementText):
    """
    String, child of L{Part}

    DTD definition::
        <!ELEMENT string (#PCDATA)>
        <!ATTLIST string
            %id;
            value CDATA         #REQUIRED
            doubled (true|false)    #IMPLIED>

    C{value} is the integer number of the string, from 1 to 7
    """
    _req_attrs = ['id_','value']
    _attrs = ['doubled']
    def __init__(self, id_, text, value, doubled=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int}, string number
        @param doubled: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.doubled = doubled

    def _get_doubled(self):
        return self._doubled
    def _set_doubled(self, value):
        self._doubled = _True_false(value)
    doubled = property(_get_doubled, _set_doubled)


class String_fingering(_ElementText):
    """
    Fingering for string, child of L{Note}, L{Interval}

    DTD definition::
        <!ELEMENT string_fingering (#PCDATA)>
        <!ATTLIST string_fingering
            %id;
            value CDATA     #REQUIRED
            line_of_continuation (start|stop)   #IMPLIED>

    C{value} from 0 to 5, with 0 used for thumb and 5 for open string.
    In case of a finger substitution on a note C{value} is written as a
    sequence of integers separated by comma, example "1,2".
    C{line_of_continuation} can be one of I{start|stop}.
    """
    _req_attrs = ['id_','value']
    _attrs = ['line_of_continuation']
    def __init__(self, id_, text, value, line_of_continuation=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: tuple of ints
        @param line_of_continuation: C{string} in ['start','stop']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value  #list of int
        self.line_of_continuation = line_of_continuation

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _Tuple_int(value)
    value = property(_get_value, _set_value)

    def _get_line_of_continuation(self):
        return self._line_of_continuation
    def _set_line_of_continuation(self, value):
        self._line_of_continuation = _Start_stop(value)
    line_of_continuation = property(_get_line_of_continuation,
        _set_line_of_continuation)


class String_position(_ElementText):
    """
    String_position, child of L{Part}

    DTD definition::
        <!ELEMENT string_position (#PCDATA)>
        <!ATTLIST string_position
            %id;
            value CDATA         #REQUIRED
            line_of_continuation (1|2)   #IMPLIED>

    C{value} is the string position, with 0 as half position
    C{line_of_continuation} can only be I{1} or I{2}.
    """
    _req_attrs = ['id_','value']
    _attrs = ['line_of_continuation']
    def __init__(self, id_, text, value, line_of_continuation=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int}, string number
        @param line_of_continuation: 1 or 2
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.line_of_continuation = line_of_continuation

    def _get_line_of_continuation(self):
        return self._line_of_continuation
    def _set_line_of_continuation(self, value):
        self._line_of_continuation = value
    line_of_continuation = property(_get_line_of_continuation,
        _set_line_of_continuation)


class Stroke(_ElementText):
    """
    Stroke, child of L{Note}

    DTD definition::
        <!ELEMENT stroke (#PCDATA)>
        <!ATTLIST stroke
            %id;
            value (up|down) #REQUIRED
            doubled (true|false)    #IMPLIED>
    """
    _req_attrs = ['id_','value']
    _attrs = ['doubled']
    def __init__(self, id_, text, value, doubled=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['up','down']
        @param doubled: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.doubled = doubled

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _Up_dn(value)
    value = property(_get_value, _set_value)

    def _get_doubled(self):
        return self._doubled
    def _set_doubled(self, value):
        self._doubled = _True_false(value)
    doubled = property(_get_doubled, _set_doubled)


class Syllabic_mute(_ElementText):
    """
    Syllabic mute, child of L{Syllable_mute}

    DTD definition::
        <!ELEMENT syllabic_mute (#PCDATA)>
        <!ATTLIST syllabic_mute
            %id;
            value (single|measure)  #REQUIRED
            doubled (true|false)    #IMPLIED>

    Braille sign for a mute syllable (not in the NIM) used to indicate a break
    in the lyric syllables. C{value} indicates whether only one syllable is mute
    or a whole measure.
    """
    _req_attrs = ['id_','value']
    _attrs = ['doubled']
    def __init__(self, id_, text, value, doubled=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['single', 'measure']
        @param doubled: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.doubled = doubled

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',
            1:'single',#51
            2:'measure',#4850
            }, 0)
    value = property(_get_value, _set_value)

    def _get_doubled(self):
        return self._doubled
    def _set_doubled(self, value):
        self._doubled = _True_false(value)
    doubled = property(_get_doubled, _set_doubled)


class Syllabic_parenthesis(_ElementText):
    """
    Syllabic parenthesis, child of L{Syllable}

    DTD definition::
        <!ELEMENT syllabic_parenthesis (#PCDATA)>
        <!ATTLIST syllabic_parenthesis
            %id;>
    """
    _req_attrs = ['id_']
    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
        _ElementText.__init__(self, id_, text)


class Syllabic_slur(_ElementText):
    """
    Syllabic slur, child of L{Note}

    DTD definition::
        <!ELEMENT syllabic_slur (#PCDATA)>
        <!ATTLIST syllabic_slur
            %id;
            value CDATA         #REQUIRED
            verses CDATA        #IMPLIED>

    Known values for C{value} attribute are C{short, long, verse}. If verse,
    the C{verses} attribute can be used to indicate to which verses this slur
    applies.
    """
    _req_attrs = ['id_','value']
    _attrs = ['verses']
    def __init__(self, id_, text, value, verses=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['short','long','verse']
        @param verses: C{tuple of int}
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.verses = verses  #verses number (tuplet of int)

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',
            1:'short',#01
            2:'long',#0101
            3:'verse',#03xx
            }, 0)
    value = property(_get_value, _set_value)

    def _get_verses(self):
        return self._verses
    def _set_verses(self, value):
        self._verses = _Tuple_int(value)
    verses = property(_get_verses, _set_verses)


class Syllabic_text(_ElementText):
    """
    Syllabic text, child of L{Syllable}

    DTD definition::
        <!ELEMENT syllabic_text (#PCDATA)>
        <!ATTLIST syllabic_text
            %id;
            value CDATA     #IMPLIED
            xml:lang CDATA  #IMPLIED>

    Is the text that forms a syllable, i.e. that is sung on a note. C{value} is
    the unicode text used in translating to other formats.
    """
    _req_attrs = ['id_']
    _attrs = ['value','lang']
    def __init__(self, id_, text, value=None, lang=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: unicode text
        @param lang: language as xml:lang
        """
        _ElementText.__init__(self, id_, text)
        self.value = value
        self.lang = lang


class Syllable(_ElementContainer):
    """
    Syllable, child of L{Lyric}, {Lyric_repeat}

    DTD definition::
        <!ELEMENT syllable ((syllabic_parenthesis,syllabic_text,syllabic_parenthesis)|
                            (syllabic_text))>
        <!ATTLIST syllable
            %id;>

    A syllable contains a text that can be enclosed in parenthesis.
    """
    _req_attrs = ['id_']
    _elements = ['syllabic_text']
    _elements_ls = ['syllabic_parenthesis']
    def __init__(self, id_):
        """ @param id_: id """
        _ElementContainer.__init__(self, id_)

    def get_syllabic_text(self):
        return self._get_element('syllabic_text')
    def set_syllabic_text(self, item):
        self._set_element('syllabic_text', item)
    #def insert_syllabic_text(self, item, next_item=None):
    #   self._insert_element('syllabic_text', item, next_item)
    def del_syllabic_text(self):
        self._del_element('syllabic_text')

    def get_syllabic_parenthesis(self):
        return self._get_element_ls('syllabic_parenthesis')
    def add_syllabic_parenthesis(self, item, index=None):
        self._add_element('syllabic_parenthesis', item, index)
    def insert_syllabic_parenthesis(self, item, next_item=None):
        self._insert_element('syllabic_parenthesis', item, next_item)
    def del_syllabic_parenthesis(self, item):
        self._del_element('syllabic_parenthesis', item)
    def extend_syllabic_parenthesis(self, items):
        self._extend_element('syllabic_parenthesis', items)


class Syllable_mute(_ElementContainer):
    """
    Syllable_mute, child of L{Lyric}, {Lyric_repeat}

    DTD definition::
        <!ELEMENT syllable_mute (syllabic_mute,number?)>
        <!ATTLIST syllable_mute
            %id;>

    A mute syllable is a place holder in a lyric text. Is composed by a
    L{Syllabic_mute} eventually followed by a L{Number} indicating the number
    of times the mute syllable need to be repeated.
    """
    _req_attrs = ['id_']
    _elements = ['syllabic_mute', 'number']
    def __init__(self, id_):
        """ @param id_: id """
        _ElementContainer.__init__(self, id_)

    def get_syllabic_mute(self):
        return self._get_element('syllabic_mute')
    def set_syllabic_mute(self, item):
        self._set_element('syllabic_mute', item)
    #def insert_syllabic_mute(self, item, next_item=None):
    #   self._insert_element('syllabic_mute', item, next_item)
    def del_syllabic_mute(self):
        self._del_element('syllabic_mute')

    def get_number(self):
        return self._get_element('number')
    def set_number(self, item):
        self._set_element('number', item)
    #def insert_number(self, item, next_item=None):
    #   self._insert_element('number', item, next_item)
    def del_number(self):
        self._del_element('number')


class Syllable_ref(_ElementProxy):
    """
    Syllable reference, child of L{Lyrics}

    DTD definition::
        <!ELEMENT syllable_ref EMPTY>
        <!ATTLIST syllable_ref
            %id_ref;
            type (begin|middle|end|single|continue|mute) #IMPLIED>

    The C{type} attribute indicate the role of the syllable in a word or a phrase.
    """
    _req_attrs = ['id_','type_']
    def __init__(self, id_, type_=None):
        """
        @param id_: id
        @param type_: C{string} in ['begin','middle','end','single','continue'
            ,'mute']
        """
        _ElementProxy.__init__(self, ref_id_=id_)
        self.type_ = type_

    def _get_type_(self):
        return self._type_
    def _set_type_(self, value):
        self._type_ = _NamedEnumerator(value, {0:'',
            1:'begin',#first syllable
            2:'middle',#middle of the text
            3:'end',#last syllable
            4:'single',#single syllable
            5:'continue',#continue from the previous syllable
            6:'mute',#mute syllable
            }, 0)
    type_ = property(_get_type_, _set_type_)

    #def is_container(self):
    #    """ hide container """
    #    return False


class Tie(_ElementText):
    """
    Tie, child of L{Note}

    DTD definition::
        <!ELEMENT tie (#PCDATA)>
        <!ATTLIST tie
            %id;
            value CDATA         #REQUIRED>

    C{value} known values are I{normal,chord,chord_doubled,arpeggio}.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['normal','chord','chord_doubled','arpeggio']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',1:'normal',2:'chord',
            3:'chord_doubled',4:'arpeggio'}, 0)
    value = property(_get_value, _set_value)


class Tie_ref(_ElementProxy):
    """
    Tie reference, child of L{Ties}

    DTD definition::
        <!ELEMENT tie_ref EMPTY>
        <!ATTLIST tie_ref
            %id_ref;
            type    (start|stop)   #REQUIRED
            start_ref  CDATA    #REQUIRED>

    See L{Slur_ref} description.
    """
    _req_attrs = ['id_','type_','start_ref']
    def __init__(self, id_, type_, start_ref):
        """
        @param id_: id
        @param type_: C{string} in ['start','stop']
        @param start_ref: reference to the starting slur.
        """
        _ElementProxy.__init__(self, ref_id_=id_)
        self.type_ = type_
        self.start_ref = start_ref

    def _get_type_(self):
        return self._type_
    def _set_type_(self, value):
        self._type_ = _Start_stop(value)
    type_ = property(_get_type_, _set_type_)

    #def is_container(self):
    #    """ hide container """
    #    return False


class Ties(_ElementContainer):
    """
    Ties, child of L{Note_data}

    DTD definition::
        <!ELEMENT ties (tie_ref+)>

    Is the container for the L{Tie_ref} elements.
    """
    _elements_ls = ['tie_ref']
    _doc_element = False  #this element has not a doc representation

    def get_tie_ref(self):
        return self._get_element_ls('tie_ref')
    def add_tie_ref(self, item, index=None):
        self._add_element('tie_ref', item, index)
    def insert_tie_ref(self, item, next_item=None):
        self._insert_element('tie_ref', item, next_item)
    def del_tie_ref(self, item):
        self._del_element('tie_ref', item)
    def extend_tie_ref(self, items):
        self._extend_element('tie_ref', items)


class Time_signature(_ElementText):
    """
    Time signature, child of L{Score_data}, L{Part}

    DTD definition::
        <!ELEMENT time_signature (#PCDATA)>
        <!ATTLIST time_signature
            %id;
            values CDATA        #REQUIRED
            csymbol (C|c)       #IMPLIED
            figure (true|false) #IMPLIED
            single_number (true|false)  #IMPLIED>

    The time signature can be written in various ways. The C{values} attribute
    is a tuple of values: for a simple time signature it is a single tuple with
    the first number as number of beats and the second one as beat duration.
    If multiple time signatures are written the C{value} attribute is a tuple,
    as ((4,1024),(3,512)) to write 4 quarters and 3 eighths, or ((3,4),1024) to
    write a 3+4 quarters.

    The C{symbol} attribute is used for common time, C, or cutted time, c.
    The C{figure} attribute is true if a note is used for the beat duration.
    The C{single_number} attribute is true if the time signature is written as
    a single number.
    """
    _req_attrs = ['id_','values']
    _attrs = ['csymbol','figure','single_number']
    def __init__(self, id_, text, values, csymbol=None, figure=None, single_number=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param values: C{tuple of tuple of ints}
        @param csymbol: C{string} in ['C','c']
        @param figure: True or False
        @param single_number: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.values = values    #tuple 3,1024
        self.csymbol = csymbol  #None,C,c
        self.figure = figure    #None,True  (denominator expressed as a figure)
        self.single_number = single_number  #None,True (signature as a single number)

    def _get_values(self):
        return self._values
    def _set_values(self, values):
        self._values = _Tuple_tuple(values)
    values = property(_get_values, _set_values)

    def _get_csymbol(self):
        return self._csymbol
    def _set_csymbol(self, value):
        self._csymbol = _NamedEnumerator(value, {0:'',1:'C',2:'c'},
            default=0)
    csymbol = property(_get_csymbol, _set_csymbol)

    def _get_figure(self):
        return self._figure
    def _set_figure(self, value):
        self._figure = _True_false(value)
    figure = property(_get_figure, _set_figure)

    def _get_single_number(self):
        return self._single_number
    def _set_single_number(self, value):
        self._single_number = _True_false(value)
    single_number = property(_get_single_number, _set_single_number)


class Tremolo(_ElementText):
    """
    Tremolo, child of L{Note}

    DTD definition::
        <!ELEMENT tremolo (#PCDATA)>
        <!ATTLIST tremolo
            %id;
            value CDATA         #REQUIRED
            doubled (true|false)    #IMPLIED>

    The tremolo sign C{value} attribute is the number of beams used for the
    tremolo.
    """
    _req_attrs = ['id_','value']
    _attrs = ['doubled']
    def __init__(self, id_, text, value, doubled=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int} from 0 to 5
        @param doubled: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #int
        self.doubled = doubled #None,True

    def _get_doubled(self):
        return self._doubled
    def _set_doubled(self, value):
        self._doubled = _True_false(value)
    doubled = property(_get_doubled, _set_doubled)


class Tremolo_ref(_ElementProxy):
    """
    Tremolo reference, child of L{Note_data}

    DTD definition::
        <!ELEMENT tremolo_ref EMPTY>
        <!ATTLIST tremolo_ref
            %id_ref;>
    """
    _req_attrs = ['id_']
    def __init__(self, id_):
        """
        @param id_: id
        """
        _ElementProxy.__init__(self, ref_id_=id_)

    #def is_container(self):
    #    """ hide container """
    #    return False


class Tuplet(_ElementText):
    """
    Tuplet, child of L{Note}, L{Rest}

    DTD definition::
        <!ELEMENT tuplet (#PCDATA)>
        <!ATTLIST tuplet
            %id;
            value CDATA         #REQUIRED
            doubled (true|false)    #IMPLIED>

    The C{value} attribute is the number written for the irregular group.
    """
    _req_attrs = ['id_','value']
    _attrs = ['doubled']
    def __init__(self, id_, text, value, doubled=None):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{int}
        @param doubled: True or False
        """
        _ElementText.__init__(self, id_, text)
        self.value = value #int
        self.doubled = doubled #None,True

    def _get_doubled(self):
        return self._doubled
    def _set_doubled(self, value):
        self._doubled = _True_false(value)
    doubled = property(_get_doubled, _set_doubled)


class Tuplet_ref(_ElementProxy):
    """
    Tuplet reference, child of L{Tuplets}

    DTD definition::
        <!ELEMENT tuplet_ref EMPTY>
        <!ATTLIST tuplet_ref
            %id_ref;
            notes   CDATA   #REQUIRED
            type    (start|stop|continue)   #REQUIRED>

    The C{notes} attribute is a combination of two values: the number of real
    notes and the number of actual notes. So a triplet have a notes value
    equals to 2,3 to indicate two notes in place of three.
    The C{type} attribute can be I{start,stop,continue}.
    """
    _req_attrs = ['id_','notes','type_']
    def __init__(self, id_, notes, type_):
        """
        @param id_: id
        @param notes: C{tuple} of real notes, written notes
        @param type_: C{string} in ['start','stop','continue']
        """
        _ElementProxy.__init__(self, ref_id_=id_)
        self.notes = notes
        self.type_ = type_

    def _get_notes(self):
        return self._notes
    def _set_notes(self, value):
        self._notes = _Tuple_int(value)
    notes = property(_get_notes, _set_notes)

    def _get_type_(self):
        return self._type_
    def _set_type_(self, value):
        self._type_ = _Start_stop_continue(value)
    type_ = property(_get_type_, _set_type_)

    #def is_container(self):
    #    """ hide container """
    #    return False


class Tuplets(_ElementContainer):
    """
    Tuplets, child of L{Note_data}, L{Rest_data}

    DTD definition::
        <!ELEMENT tuplets (tuplet_ref+)>

    L{Tuplet_ref} container.
    """
    _elements_ls = ['tuplet_ref']
    _doc_element = False  #this element has not a doc representation

    def get_tuplet_ref(self):
        return self._get_element_ls('tuplet_ref')
    def add_tuplet_ref(self, item, index=None):
        self._add_element('tuplet_ref', item, index)
    def insert_tuplet_ref(self, item, next_item=None):
        self._insert_element('tuplet_ref', item, next_item)
    def del_tuplet_ref(self, item):
        self._del_element('tuplet_ref', item)
    def extend_tuplet_ref(self, items):
        self._extend_element('tuplet_ref', items)


class Unknown(_ElementText):
    """
    Unknown, child of L{Score_data}, L{Part}

    DTD definition::
        <!ELEMENT unknown (#PCDATA)>
        <!ATTLIST unknown
            %id;>

    Each element that is not yet defined in the BMML code can be encoded as an
    unknown element.

    @todo: add a value attribute to encode other information that can be useful,
    for example user information
    """
    _req_attrs = ['id_']
    def __init__(self, id_, text):
        """
        @param id_: id
        @param text: unicode braille text
        """
        _ElementText.__init__(self, id_, text)


class Value_prefix(_ElementText):
    """
    Value prefix, child of L{Note}, L{Rest}

    DTD definition::
        <!ELEMENT value_prefix (#PCDATA)>
        <!ATTLIST value_prefix
            %id;
            value (separator|large|small|256th)         #REQUIRED>

    Prefix for defining the duration of a L{Note} or a L{Rest} or used as
    distiction of value.
    """
    _req_attrs = ['id_','value']
    def __init__(self, id_, text, value):
        """
        @param id_: id
        @param text: unicode braille text
        @param value: C{string} in ['separator','large','small','256th']
        """
        _ElementText.__init__(self, id_, text)
        self.value = value

    def _get_value(self):
        return self._value
    def _set_value(self, value):
        self._value = _NamedEnumerator(value, {0:'',
            1:'separator',2:'large',3:'small',4:'256th'}, 0)
    value = property(_get_value, _set_value)


